P3396 哈希冲突 (分块)

题意:

给定长度为n的序列a,现在要进行m次操作,操作有两种:
1.给定x,y,询问下标膜x等于y的所有位置的和
2.给定x,y,将a[x]修改为y

数据范围:n<=150000

解法:

令sq=sqrt(n)
预处理和维护模数小于等于sq的时候的答案
当模数大于sq的时候,暴力循环,循环次数不超过sq

code:

#include<bits/stdc++.h>
using namespace std;
const int maxm=150000+5;
const int sq=400;
int f[sq+5][sq+5];//f[i][j]表示下标膜i等于j的位置的和
int a[maxm];
int n,q;
signed main(){
    cin>>n>>q;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        for(int p=1;p<=sq;p++){
            f[p][i%p]+=a[i];
        }
    }
    while(q--){
        char op;cin>>op;
        int x,y;cin>>x>>y;
        if(op=='A'){//ask
            if(x<=sq){
                cout<<f[x][y]<<endl;
            }else{
                int ans=0;
                for(int i=y;i<=n;i+=x){
                    ans+=a[i];
                }
                cout<<ans<<endl;
            }
        }else if(op=='C'){//change
            for(int p=1;p<=sq;p++){
                f[p][x%p]-=a[x];
                f[p][x%p]+=y;
            }
            a[x]=y;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/107511601