數據結構入門5—分塊

發現分塊真的是一個好東西,就是優化過後的暴力啊

當修改的時間複雜度爲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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章