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;
}
/*
*/
要拿牌啊

浙公网安备 33010602011771号