洛谷P3396 哈希冲突 根号分治模板 题解

题面

做这道题的时候我在练分块,实际上做的都是些有点水的题。结果一下子看到这道题。

这什么玩意?稍微镇定一下,想了想。大的暴力,小的写数据结构维护?

然后过了,我现在甚至一时半会想不起来怎么做的了。

做法

对于池子的x。

对于x<=n1/2,直接暴力建池子pool[ i ][ j ],表示对于池子长度i,模数为j的对应位置的数的总和。

每次修改,对于这些小池子直接暴力修改,预期修改n1/2次,对于大池子直接不管了,后面直接查。

至于查询池子x,对于x>n1/2,在这个池子里的数不超过n1/2个,暴力查询这个池子里的数,求和。

对于x<=n1/2,之前对这个范围建过池子了,甚至可以直接O(1)查询。

时间复杂度n3/2,可以通过本题。

#include<bits/stdc++.h>
using namespace std;
const int h=150010;
int len;
int n,m;
int value[h];
int b_sum[h];
int pool[1010][1010];
int main(){
    scanf("%d%d",&n,&m);
    len=sqrt(n); 
    for(int i=1;i<=n;i++){
        scanf("%d",&value[i]);
        for(int j=1;j<=len;j++)
            pool[j][i%j]+=value[i];
    }      
    char op;
    int x,y,ans;
    for(int i=1;i<=m;i++){
        cin>>op;
        scanf("%d%d",&x,&y),ans=0;
        if(op=='C'){
            for(int j=1;j<=len;j++)
                pool[j][x%j]+=y-value[x];
            value[x]=y;
        }          
        else{
            if(x<=len)
                ans=pool[x][y];
            else
                for(int j=0;x*j+y<=n;j++)
                    ans+=value[x*j+y];
            printf("%d\n",ans);
        }           
    }
    return 0;
}
完整代码

 

posted on 2022-11-12 21:58  timedrop  阅读(26)  评论(0编辑  收藏  举报