(事業部の定格。2)教育Codeforcesラウンド71 -F。残りProblem-技巧分块
【問題の内容】
最初の\([1,500000]は\)二つの連続操作があり、0です。
\(1 \) 、\([X] \)の値プラス\(Y \) 。
\(2 \) 、全て満足することが求め\(iはMOD \ X = \ Yを\) \([I] \)とを。
【溶液】
特定のアプローチは、最初のために、ある\(\のSQRT {500000} = 708 \) 番号の定義\(DP [j] [kは ] \) 全ての真表す\(iはMODの\ J = \のk \)を\を( [I] \)と。各時間\(1 \)動作時間、\(O(\ SQRT {500000})\)の前処理に関する。できるクエリ\(O(1)\)のクエリ。
より大きいため(O(\ SQRT {500000} )\)\ 数、解決することができる暴力:\(I MODが\ X = Y \ Leftrightarrow I + X \ CDOT T = Yを\ \) 。そうのみ列挙する必要が\(\ FRAC {500000} { X} \) 回。そして\(Xが\)以上である\(\のSQRT {500000})= 708 \)、列挙の数よりも大きくないように(708 \)\回程度の全体的な複雑\(O(500000 ^ {\ FRAC {3 {2}}})\)。
【コード】
/*
* @Author: Simon
* @Date: 2019-08-28 14:34:47
* @Last Modified by: Simon
* @Last Modified time: 2019-08-28 15:02:25
*/
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 1005
#define maxm 500005
int dp[maxn][maxn]/*下标满足模i余数为j的 值的和*/,a[maxm];
int main(){
#ifndef ONLINE_JUDGE
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int q,m=ceil(sqrt(maxm));cin>>q;
while(q--){
int p,x,y;cin>>p>>x>>y;
if(p==1){
a[x]+=y;
for(int i=1;i<=m;i++) dp[i][x%i]+=y;
}
else{
if(x<=m) cout<<dp[x][y]<<endl;
else{
int ans=0;
for(int i=y;i<maxm;i+=x) ans+=a[i];
cout<<ans<<endl;
}
}
}
#ifndef ONLINE_JUDGE
cout<<endl;system("pause");
#endif
return 0;
}