F. Remainder Problem 解题报告
F. Remainder Problem解题报告 \(\LaTeX\)
我的第一道根号分治,感觉没啥好讲的(我讲不出来),裸的根号分治,但不是神的。
根号分治
在本题中,注意到 \(5\times 10^5\) 很大,\(n\) 和 \(q\) 同阶 ,模数很小时最坏可以卡成 \(O(n^2)\) 但是注意到当操作 \(2\) 模数 \(x>\sqrt{n}\) 时,可以隔 \(x\) 个跳着选,则单次操作 \(2\) 复杂度可以保证在 \(O(\sqrt{n})\) ,但是当模数 \(x<\sqrt{n}\) 时,上述做法复杂度就难以保证在根号。但是又注意到 \(\sqrt{n}^2=n\) 可以设计 dp 状态并转移,\(f[i][j]\) 表示 \(\sum_{1}^{\sqrt{n}}a[x]\times[x\mod i=j]\) 单次操作复杂度在 \(\sqrt{n}\) 。则总时间复杂度 \(O(n\sqrt{n})\) ,注意不用开 \(long long\) 。
代码
实践上出了点锅,可能与理论有点小差,代码超超超短,\(\textcolor{skyblue}{蓝色}\)是水的颜色~
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5,man=1020;
int q,a[maxn+100],f[man+100][man+100];
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>q;
while(q--){
int t,x,y;
cin>>t>>x>>y;
if(t==1){//O(sqrt(n))
for(int i=1;i<man;++i)f[i][x%i]+=y;
a[x]+=y;
}
if(t==2){
if(x>man){
int cnt=0;
for(int i=y;i<=maxn;i+=x)cnt+=a[i];//O(sqrt(n))
cout<<cnt<<"\n";
}
else cout<<f[x][y]<<"\n";
}
}
return 0;
}

浙公网安备 33010602011771号