解題:洛谷3396 雜湊衝突
阿新 • • 發佈:2018-11-13
題外話:現在還不知道退不退役啊QAQ,因為發揮太渣,把Day1T3和Day2T1這僅有的兩道有區分度的題全寫掛了(沒區分度的其他題**倒挺穩。。。),退不退役全看資料溼度了(400-460,教練建議的線是420,orz i207M 530+)
在可能是苟在機房的最後一週裡打算學學分塊和莫隊=。=
分塊不只是一種處理序列問題的方法,更多的是一種均攤複雜度的思想(比如這個題)
(我好像在彙總裡寫過這個思想)
我們現在有兩種暴力:第一種暴力是$O(mod)$的,即先$O(n*mod)$處理在模某數意義下每個池子裡的數,然後每次$O(1)$查表+$O(mod)$修改,問題是模數很大時會GG;第二種暴力是$O(\frac{n}{mod})$,直接在序列上每隔$mod$統計,然後$O(1)$修改一下序列。然後你把這兩種暴力揉在一起,對於$mod<=sqrt(n)$的情況採用暴力1,對於$mod>sqrt(n)$的情況採用暴力2,於是得到了一個$O((n+m)sqrt(n))$的演算法
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=150005,Sqrt=390; 6 long long a[N],bkt[Sqrt+5][Sqrt+5]; 7 int n,m,t1,t2; char rd[5]; 8 int main () 9 { 10 scanf("%d%d",&n,&m); 11 for(int i=1;i<=n;i++)View Code12 { 13 scanf("%lld",&a[i]); 14 for(int j=1;j<=Sqrt;j++) 15 bkt[j][i%j]+=a[i]; 16 } 17 while(m--) 18 { 19 scanf("%s%d%d",rd,&t1,&t2); 20 if(rd[0]=='A') 21 { 22 if(t1<=Sqrt) 23 printf("%lld\n",bkt[t1][t2%t1]); 24 else 25 { 26 long long ans=0; 27 for(int i=t2;i<=n;i+=t1) 28 ans+=a[i]; 29 printf("%lld\n",ans); 30 } 31 } 32 else 33 { 34 for(int i=1;i<=Sqrt;i++) 35 bkt[i][t1%i]+=t2-a[t1]; 36 a[t1]=t2; 37 } 38 } 39 return 0; 40 }