专栏文章
题解:CF1921F Sum of Progression
CF1921F题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqutrne
- 此快照首次捕获于
- 2025/12/04 11:06 3 个月前
- 此快照最后确认于
- 2025/12/04 11:06 3 个月前
根号分治模板题。
对于这种题目,直接暴力显然是不行的。于是要用到根号分治。
根号分治的基本思路就是设一个阈值 ,然后根据询问的大小分 种情况讨论:
这种情况下直接暴力。
CPPif (d>=B){
int ans=0;
for (int now=s,i=1;i<=k;now+=d,i++){
ans+=a[now]*i;
}
cout<<ans<<' ';
}
这种情况下需要预处理。我们设
(中括号不是艾弗森括号,只是普通的中括号)。
然后:
CPP
for (int i=1;i<B;i++){
for (int j=1;j<=n;j++){
if (j<=i) sum[i][j]=a[j],sum2[i][j]=a[j];
else sum[i][j]=sum[i][j-i]+(j+i-1)/i*a[j],sum2[i][j]=sum2[i][j-i]+a[j];
}
}
于是有:
(式子稍微有点长,具体可以看代码)。
CPPelse{
int L=s,R=s+(k-1)*d;
int ans1=sum[d][R]-sum[d][L-d];
int cnt=(s+d-1)/d-1;
int ans2=cnt*(sum2[d][R]-sum2[d][L-d]);
cout<<ans1-ans2<<' ';
}
那么时间复杂度为 。这个式子在 时取到最小值,所以这种技巧叫做根号分治。
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...