洛谷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; }