luogu3396 哈希冲突

参考这里
我们先预处理模数在 \(\sqrt{n}\) 以内的询问。
要是模数在 \(\sqrt{n}\) 以外,直接暴力统计,反正这样的数又不会超过 \(\sqrt{n}\) 个。
修改的时候也是。要是在 \(\sqrt{n}\) 以内就把预处理的答案减去原数加上新数。
然后再把原数改掉。
然后再优化一下,不预处理了,询问的时候我们再计算答案并保存下来。

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int ans[391][391], n, m, a[150005], uu, vv, blc;
char ss[15];
bool vis[391];
int getAns(int uu, int vv){
	if(uu<=blc){
		if(!ans[uu][vv])
			for(int i=vv; i<=n; i+=uu)
				ans[uu][vv] += a[i];
		return ans[uu][vv];
	}
	else{
		int re=0;
		for(int i=vv; i<=n; i+=uu)
				re += a[i];
		return re;
	}
}
void change(int uu, int vv){
	for(int i=1; i<=blc; i++)
		if(ans[i][uu%i])
			ans[i][uu%i] = ans[i][uu%i] - a[uu] + vv;
	a[uu] = vv;
}
int main(){
	cin>>n>>m;
	blc = sqrt(n);
	for(int i=1; i<=n; i++)
		scanf("%d", &a[i]);
	while(m--){
		scanf("%s %d %d", ss, &uu, &vv);
		if(ss[0]=='A')	printf("%d\n", getAns(uu, vv));
		else	change(uu, vv);
	}
	return 0;
}
posted @ 2018-01-15 16:46  poorpool  阅读(123)  评论(0编辑  收藏  举报