P7482 题解
思路
cdq 分治拆成
对于一个区间计算答案可以用 dp 完成。以
记跨过
记
后面两个直接做,前面的对于每个
对
其余的递归
然后发现一个 sub 都没过。原因是不一定一定要选
code
int n,a[maxn],ans;
int f[maxn][2],g[maxn];
int b[maxn],len,sum[maxn];
void sovle(int l,int r){
if(l==r){
(ans+=a[l])%=mod;
return ;
}
int mid=l+r>>1;
f[mid][0]=0,f[mid][1]=a[mid];
if(mid-1>=l)f[mid-1][0]=a[mid-1],f[mid-1][1]=max(a[mid-1],a[mid]);
for(int i=mid-2;i>=l;i--){
f[i][0]=max(f[i+1][0],f[i+2][0]+a[i]);
f[i][1]=max(f[i+1][1],f[i+2][1]+a[i]);
}
f[mid+1][0]=0,f[mid+1][1]=a[mid+1];
if(mid+2<=r)f[mid+2][0]=a[mid+2],f[mid+2][1]=max(a[mid+2],a[mid+1]);
for(int i=mid+3;i<=r;i++){
f[i][0]=max(f[i-1][0],f[i-2][0]+a[i]);
f[i][1]=max(f[i-1][1],f[i-2][1]+a[i]);
}
int sl=0,sr=0;
for(int i=l;i<=mid;i++)(sl+=f[i][0])%=mod;
for(int i=mid+1;i<=r;i++)(sr+=f[i][0])%=mod;
(ans+=sl*(r-mid)+sr*(mid-l+1))%=mod;
// cout<<l<<" "<<r<<" "<<ans<<"\n";
for(int i=l;i<=r;i++)g[i]=f[i][1]-f[i][0];
len=0;
for(int i=mid+1;i<=r;i++)b[++len]=g[i];
sort(b+1,b+len+1);sum[len+1]=0;
for(int i=len;i>=1;i--)sum[i]=(sum[i+1]+b[i]%mod+mod)%mod;
for(int i=l;i<=mid;i++){
int p=upper_bound(b+1,b+len+1,g[i])-b;
(ans+=(g[i]%mod+mod)*(p-1)+sum[p])%=mod;
// cout<<i<<" "<<g[i]<<" "<<p<<" "<<sum[p]<<"\n";
}
sovle(l,mid),sovle(mid+1,r);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?