2023.7.13拷逝
T1
看到最大值最小,考虑二分答案。接下来考虑如何构造
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll n,sa,sb,sc,sd,a[5000005],f[5000005],sum[5000005],maxn,minn,mod;
ll fun(ll x){
return (sa*x%mod*x%mod*x%mod+sb*x%mod*x%mod+sc*x%mod+sd)%mod;
}
int main(){
freopen("Bell.in","r",stdin);
freopen("Bell.out","w",stdout);
scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&sa,&sb,&sc,&sd,&a[1],&mod);
sum[1]=maxn=minn=a[1];
for(int i=2;i<=n;++i){
a[i]=(fun(a[i-1])+fun(a[i-2]))%mod;
maxn=max(maxn,a[i]);
minn=min(minn,a[i]);
sum[i]=(sum[i-1]+a[i])%mod;
}
ll l=minn,r=maxn,mid;
while(l<r){
mid=(l+r)>>1;
f[1]=a[1]-mid;
bool ok=1;int pos;
for(int i=2;i<=n;++i){
f[i]=f[i-1];
if(a[i]-f[i]>mid){
f[i]=a[i]-mid;
}
else if(f[i]-a[i]>mid){
ok=0;pos=i;break;
}
}
if(ok)
r=mid;
else
l=mid+1;
}
printf("%lld\n",r);
fclose(stdin);fclose(stdout);
return 0;
}
T2
首先开一个桶,对于当前的
如何判断是否回文?只需要开一个值域树状数组,然后哈希处理即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#define ll long long
using namespace std;
const ll mod=1e9+7;
ll n,a[500005],pos[500005],h[500005],c[500005][2];
void add(ll x,ll w,ll id){
while(x<=n)
c[x][id]=(c[x][id]+w)%mod,x+=x&(-x);
}
ll ask(ll x,ll id){
ll re=0;
while(x)
re=(re+c[x][id])%mod,x-=x&(-x);
return re;
}
int main(){
//freopen("Odd.in","r",stdin);
//freopen("Odd.out","w",stdout);
scanf("%lld",&n);
for(int i=1;i<=n;++i)
scanf("%lld",&a[i]);
h[0]=1;
for(int i=1;i<=n;++i)
h[i]=h[i-1]*233%mod;
for(int i=1;i<=n;++i){
ll len=min(a[i],n-a[i]+1);
ll w1=(ask(a[i],0)-ask(a[i]-len,0)+mod)%mod;
ll w2=(ask(a[i]+len-1,1)-ask(a[i]-1,1)+mod)%mod;
add(a[i],h[a[i]],0);add(a[i],h[n-a[i]+1],1);
if(w1*h[n-a[i]-len+2]%mod!=w2*h[a[i]-len+1]%mod){
printf("YES\n");return 0;
}
}
printf("NO\n");
fclose(stdin);fclose(stdout);
}
T3
较为简单的斜率优化DP (虽然说我在考场上也没写出来吧)
首先推柿子:(假设平均数为
所以只需要将原序列分成
设
然后斜率优化就
#include<iostream>
#include<cstdio>
using namespace std;
long long n,m,ans,f[3005][3005],a[5005],sum[3005],sum2,r[3005],l[3005];int q[3005][3005];
long long dy(long long a,long long b,long long j){
return f[q[a][j]][j]+sum[q[a][j]]*sum[q[a][j]]-f[q[b][j]][j]-sum[q[b][j]]*sum[q[b][j]];
}
long long dx(long long a,long long b,long long j){
return sum[q[a][j]]-sum[q[b][j]];
}
long long dy2(long long i,long long b,long long j){
return f[i][j]+sum[i]*sum[i]-f[q[b][j]][j]-sum[q[b][j]]*sum[q[b][j]];
}
long long dx2(long long i,long long b,long long j){
return sum[i]-sum[q[b][j]];
}
void work2(){
for(int i=1;i<=n;++i)
for(int j=0;j<=m;++j)
f[i][j]=1e18;
f[0][0]=0;
for(int i=1;i<=m;++i)
q[l[i]=r[i]=1][0]=0;
for(int j=1;j<=m;++j)
for(int i=j;i<=n;++i){
while(l[j-1]<r[j-1]&&(dy(l[j-1]+1,l[j-1],j-1)<=2*sum[i]*dx(l[j-1]+1,l[j-1],j-1)))
++l[j-1];
f[i][j]=f[q[l[j-1]][j-1]][j-1]+(sum[i]-sum[q[l[j-1]][j-1]])*(sum[i]-sum[q[l[j-1]][j-1]]);
while(l[j]<r[j]&&dy(r[j],r[j]-1,j)*dx2(i,r[j],j)>=dy2(i,r[j],j)*dx(r[j],r[j]-1,j))
--r[j];
q[++r[j]][j]=i;
}
ans=m*f[n][m]-sum[n]*sum[n];
}
int main(){
//freopen("journey.in","r",stdin);
//freopen("journey.out","w",stdout);
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
sum2+=a[i]*a[i];
}
work2();
printf("%lld\n",ans);
fclose(stdin);fclose(stdout);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】