题目
众所周知,模数的hash会产生冲突。例如,如果模的数p=7,那么4和11便冲突了。
B君对hash冲突很感兴趣。他会给出一个正整数序列value[]。
自然,B君会把这些数据存进hash池。第value[k]会被存进(k%p)这个池。这样就能造成很多冲突。
B君会给定许多个p和x,询问在模p时,x这个池内数的总和。
另外,B君会随时更改value[k]。每次更改立即生效。
保证1<=p
分析
开数组ans[p][x]表示模p为x的答案,查询O(1).
考虑分块
观察暴力的模式,每次加p,当p足够大时所需次数其实很少【比如sqrt(n)】
我们就对sqrt(n)以内的p预处理,大于sqrt(n)的暴力
code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=150000;
int ans[405][405];
int a[maxn];
int n,m;
int block;
char c[10];
int main()
{
scanf("%d%d",&n,&m);
block=sqrt(n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=block;j++)
ans[j][i%j]+=a[i];
}
for (int i=1;i<=m;i++)
{
scanf("%s",c);
if (c[0]=='A')
{
int x,y;
scanf("%d%d",&x,&y);
if (x<=block)
{
printf("%d\n",ans[x][y]);
}
else
{
int sum=0;
for (int i=y;i<=n;i=i+x)
sum+=a[i];
printf("%d\n",sum);
}
}
else
{
int x,y;
scanf("%d%d",&x,&y);
for (int i=1;i<=block;i++)
{
ans[i][x%i]=ans[i][x%i]-a[x]+y;
}
a[x]=y;
}
}
}