P3396 哈希冲突
P3396 哈希冲突
题目描述
众所周知,模数的hash会产生冲突。例如,如果模的数
p=7,那么4和11便冲突了。B君对hash冲突很感兴趣。他会给出一个正整数序列
value[]。自然,B君会把这些数据存进hash池。第
value[k]会被存进(k%p)这个池。这样就能造成很多冲突。B君会给定许多个
p和x,询问在模p时,x这个池内数的总和。另外,B君会随时更改
value[k]。每次更改立即生效。保证1<=p<n1<=p<n.
输入输出格式
输入格式:
第一行,两个正整数
n,m,其中n代表序列长度,m代表B君的操作次数。第一行,
n个正整数,代表初始序列。接下来
m行,首先是一个字符cmd,然后是两个整数x,y。
若
cmd='A',则询问在模x时,y池内数的总和。若
cmd='C',则将value[x]修改为y。
输出格式:
对于每个询问输出一个正整数,进行回答。
- 本题的思路很巧妙:只预处理出前sqrt(n)部分的答案,询问时如果x<=sqrt(n),直接O(1)输出答案,否则暴力计算即可(因为x>sqrt(n)所以需要统计的个数也不超过sqrt(n))
如果p超过size,我们就暴力统计并回答。因为 p>\sqrt{n}p>n
代码:
#include <cstdio>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define res register int
//typedef long long LL;
inline int read()
{
int x(0),f(1); char ch;
while(!isdigit(ch=getchar())) if(ch=='-') f=-1;
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return f*x;
}
const int N=150000+10;
int v[N],ans[500][500];//sqrt(N) = 400
// mod p = x
int n,m,t;
int main()
{
n=read(); m=read();
t=sqrt(1.0*n);
for(res i=1 ; i<=n ; ++i)
v[i]=read();
for(res i=1 ; i<=n ; ++i)
for(res j=1 ; j<=t ; ++j)
ans[j][i%j] += v[i];
for(res k=1 ; k<=m ; ++k)
{
char s;
cin>>s;
int x=read(),y=read();
if(s=='A')
{
if(x<=t) printf("%d\n",ans[x][y]);
else
{
int tmp=0;
for(res i=y ; i<=n ; i+=x)
tmp+=v[i];
printf("%d\n",tmp);
}
}
else if(s=='C')
{
for(res p=1 ; p<=t ; ++p)
ans[p][x%p]+=(y-v[x]);
v[x]=y;
}
}
return 0;
}

浙公网安备 33010602011771号