Remainder Problem(CF 1207 F)
题目大意
你有一个长度为\(500000\)的数组,每个位置上的数初始值为\(0\),有\(q\)次操作,每次的操作有两种:\(1、1\ x\ y\)表示对第\(x\)个位置上的数加\(y\);\(2、2\ x\ y\)表示要求你输出所有对\(x\)取模后为\(y\)的位置的和。
思路
这题是一个模数分块,就是当\(x> \sqrt n\)时可以暴力查找,然后小范围的时候可以维护\(dp[x][y]\)为所有对\(x\)取模后为\(y\)的位置的和,然后就可以直接输出答案,然后就结束了。
代码
#include<bits/stdc++.h>
using namespace std;
const int n=sqrt(500000);
const int N=n+5;
int dp[N][N];
int a[500005];
int main()
{
int _;
scanf("%d",&_);
while(_--)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
for(int i=1;i<=n;i++)
{
dp[i][x%i]+=y;
}
a[x]+=y;
}
else
{
if(x<=n)printf("%d\n",dp[x][y]);
else
{
long long ans=0;
for(int i=y;i<=500000;i+=x)
{
ans+=a[i];
}
printf("%d\n",ans);
}
}
}
return 0;
}