發現分塊真的是一個好東西,就是優化過後的暴力啊。
當修改的時間複雜度爲O(n)而查詢複雜度爲O(1)或修改O(1)查詢O(n)時用分塊就可以轉化爲修改查詢都是O(sqrt(n))的。
雖然比log n要差一些,但是分塊真的很好寫啊。。
比如一道LCT模板題 彈飛綿羊
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=200000+10;
int n,m,sz,lp[maxn],tot;
int to[maxn],nd[maxn],id[maxn],jp[maxn];
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
int main() {
n=read(); sz=sqrt(n);
for(int i=1;i<=n;i+=sz) lp[++tot]=i;
lp[++tot]=n+1;id[n+1]=tot;
int x=1,y,z;
for(int i=1;i<=n;++i) to[i]=min(read()+i,n+1),id[i]= i>=lp[x+1]? ++x : x ;
for(int i=n;i>=1;--i) {
if(id[to[i]]==id[i]) nd[i]=nd[to[i]]+1,jp[i]=jp[to[i]];
else nd[i]=1,jp[i]=to[i];
}
m=read();
for(int i=1;i<=m;++i) {
x=read();y=read()+1;
if(x==1) {
z=0;
while(id[y]!=tot) {
z+=nd[y];
y=jp[y];
}
printf("%d\n",z);
}
else {
z=min(read()+y,n+1);
to[y]=z;
for(int j=y;j&&id[j]==id[y];j--) {
if(id[to[j]]==id[j]) nd[j]=nd[to[j]]+1,jp[j]=jp[to[j]];
else nd[j]=1,jp[j]=to[j];
}
}
}
return 0;
}