【洛谷P3396】哈希冲突【分块】
题目大意:
题目链接:https://www.luogu.org/problemnew/show/P3396
给出一个数列,其中第个数在下会被装进第个哈希池。维护一下两种操作:
- :询问在下池内的数字之和
- :将第个数字改成
思路:
根号算法好题。
应该不算分块吧。。。
对于这道题,我们分开两段维护:
- 模数。此时我们预处理出表示在模下池的元素之和。每次询问,预处理。
- 模数。此时我们只要从开始,暴力求答案,每次。这样的话要找个答案,时间复杂度。
为了均摊时间复杂度,我们令。显然时时间复杂度较为平均。
总时间复杂度
代码:
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=150010,M=410;
int n,m,T,x,y,a[N],cnt[M][M];
char ch;
int main()
{
scanf("%d%d",&n,&m);
T=sqrt(n);
if (T*T<n) T++;
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
for (int j=1;j<=T;j++)
cnt[j][i%j]+=a[i];
}
while (m--)
{
while (ch=getchar()) if (ch=='A'||ch=='C') break;
if (ch=='A')
{
scanf("%d%d",&x,&y);
if (x<=T) printf("%d\n",cnt[x][y]);
else
{
int ans=0;
for (int i=y;i<N;i+=x)
ans+=a[i];
printf("%d\n",ans);
}
}
else
{
scanf("%d%d",&x,&y);
for (int j=1;j<=T;j++)
cnt[j][x%j]-=a[x];
a[x]=y;
for (int j=1;j<=T;j++)
cnt[j][x%j]+=a[x];
}
}
return 0;
}