P3396 哈希冲突

题意:

给定\(n\)个数,有m次的两种操作:1.把下标模x==y的数求和,2修改x位置的值(\(n\leq15000\)\(m\leq15000\))?

题解:

根号的写法,我们把模数小于根号的数先处理出来,即对于每一种小于根号的模数把所有的值算出来,如果模数大于根号的直接暴力求解,两种操作的时间复杂度都为根号。

#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define rep(i,a,n)  for(int i=a;i<=n;i++)
#define pb push_back
const ll mod=1e9+7;
using namespace std;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b){ll ret=1; while(b){if(b&1)ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret;}
const int N=2e5+5;
int n,m,sqn,x,y,a[N],f[505][505];
char s;
int main(){
	//freopen("testdata.in","r",stdin);
	//freopen("testout.out","w",stdout);
	cin>>n>>m;sqn=sqrt(n);
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=500;i++){
	for(int j=1;j<=n;j++)
	f[i][j%i]+=a[j];
	}	
	for(int i=1;i<=m;i++){
	cin>>s>>x>>y;
	if(s=='A'){
	if(x<=500){
		printf("%d\n",f[x][y]);
	}else{
	int ans=0;
	for(int j=y;j<=n;j+=x)	ans+=a[j];
	printf("%d\n",ans);
	}	
	}else{
	int tmp=a[x];a[x]=y;
	for(int j=1;j<=500;j++){
	f[j][x%j]+=y-tmp;		
						
}		
}
}

	return 0;
}
/*

  */
posted @ 2021-03-04 13:29  喜欢李知恩IU  阅读(56)  评论(0)    收藏  举报