高级数据结构模板

可持久化并查集[BZOJ3673]


#include<bits/stdc++.h>
using namespace std;
const int N=2000005;
int n,m,a,b,op,tot,root[N],lc[N],rc[N],deep[N],fa[N];
int read(){
	int num=0;char ch=getchar();
	while(isdigit(ch)==0)ch=getchar();
	while(isdigit(ch)!=0){num=num*10+ch-'0';ch=getchar();}
	return num;
}
void build(int &o,int L,int R){
	if(!o)o=++tot;
	if(L==R){fa[o]=L;return;}
	int M=L+R>>1;
	build(lc[o],L,M);
	build(rc[o],M+1,R);
}
void modify(int &o,int L,int R,int last,int pos,int val){
	o=++tot;
	if(L==R){fa[o]=val,deep[o]=deep[last];return;}
	lc[o]=lc[last],rc[o]=rc[last];
	int M=L+R>>1;
	if(pos<=M)modify(lc[o],L,M,lc[last],pos,val);
	else modify(rc[o],M+1,R,rc[last],pos,val);
}
int query(int o,int L,int R,int pos){
	if(L==R)return o;
	int M=L+R>>1;
	if(pos<=M)return query(lc[o],L,M,pos);
	else return query(rc[o],M+1,R,pos);
}
void add(int o,int L,int R,int pos){
	if(L==R){deep[o]++;return;}
	int M=L+R>>1;
	if(pos<=M)add(lc[o],L,M,pos);
	else add(rc[o],M+1,R,pos);
}
int find(int root,int x){
	int p=query(root,1,n,x);
	if(x==fa[p])return p;
	return find(root,fa[p]);
}
int main()
{
	n=read(),m=read();
	build(root[0],1,n);
	for(int i=1;i<=m;i++){
		op=read();
		if(op==1){
			root[i]=root[i-1];
			a=read(),b=read();
			int p=find(root[i],a),q=find(root[i],b);
			if(fa[p]==fa[q])continue;
			if(deep[p]>deep[q])swap(p,q);
			modify(root[i],1,n,root[i-1],fa[p],fa[q]);
			if(deep[p]==deep[q])add(root[i],1,n,fa[q]);
		}else if(op==2){
			a=read();root[i]=root[a];
		}else{
			root[i]=root[i-1];
			a=read(),b=read();
			int p=find(root[i],a),q=find(root[i],b);
			if(fa[p]^fa[q])puts("0");
			else puts("1");
		}
	}return 0;
}

树套树[BZOJ3196]


//BIT套动态开点权值线段树
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
const int N=5e4+10;
const int inf=1e8;
int ch[N*200][2],v[N*200],root[N],num[N],tmp1[N],tmp2[N],tot=0,x,a,b,c,d,n,m;
inline int lowbit(int x){return x&-x;}
void add(int &o,int L,int R,int x,int p){
	if(!o)o=++tot;
	if(L==R)v[o]+=p;
	else{
		int M=L+R>>1;
		if(x<=M)add(ch[o][0],L,M,x,p);
		else add(ch[o][1],M+1,R,x,p);
		v[o]=v[ch[o][0]]+v[ch[o][1]];
	}
}
void change(int x,int p){
	int tmp=num[x];
	for(;x<=N;x+=lowbit(x)){
		if(tmp!=-1)add(root[x],0,inf,tmp,-1);
		add(root[x],0,inf,p,1);
	}
}
bool pushdown(int L,int R,int k){
	bool ans=0;
	for(;R;R-=lowbit(R))tmp1[R]=ch[tmp1[R]][k],ans|=tmp1[R];
	for(;L;L-=lowbit(L))tmp2[L]=ch[tmp2[L]][k],ans|=tmp2[L];
	return ans;
}
void reset(int L,int R){
	for(int i=R;i;i-=lowbit(i))tmp1[i]=root[i];
	for(int i=L;i;i-=lowbit(i))tmp2[i]=root[i];
}
int query1(int L,int R,int ql,int qr,int k){
	if(k<0||L==R)return 1;
	int M=L+R>>1;
	if(k<=M){
		if(!pushdown(ql,qr,0))return 1;
		return query1(L,M,ql,qr,k);
	}else{
		int w=0;
		for(int i=qr;i;i-=lowbit(i))w+=v[ch[tmp1[i]][0]];
		for(int i=ql;i;i-=lowbit(i))w-=v[ch[tmp2[i]][0]];
		if(!pushdown(ql,qr,1))return w+1;
		return w+query1(M+1,R,ql,qr,k);
	}
}
int query2(int L,int R,int ql,int qr,int k){
	if(k<=0)return -1;
	int w=0;
	for(int i=qr;i;i-=lowbit(i))w+=v[tmp1[i]];
	for(int i=ql;i;i-=lowbit(i))w-=v[tmp2[i]];
	if(w<k)return -1;
	if(L==R)return L;
	int M=L+R>>1;w=0;
	for(int i=qr;i;i-=lowbit(i))w+=v[ch[tmp1[i]][0]];
	for(int i=ql;i;i-=lowbit(i))w-=v[ch[tmp2[i]][0]];
	if(k<=w){
		pushdown(ql,qr,0);
		return query2(L,M,ql,qr,k);
	}else{
		pushdown(ql,qr,1);
		return query2(M+1,R,ql,qr,k-w);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(num,-1,sizeof(num));
	rep(i,1,n){scanf("%d",&x);change(i,x);num[i]=x;}
	while(m--){
		scanf("%d%d%d",&a,&b,&c);
		if(a==3){change(b,c);num[b]=c;}
		else{
			scanf("%d",&d);
			if(a==1){
				reset(b-1,c);
				printf("%d\n",query1(0,inf,b-1,c,d));
			}
			if(a==2){
				reset(b-1,c);
				printf("%d\n",query2(0,inf,b-1,c,d));
			}
			if(a==4){
				reset(b-1,c);
				int rk=query1(0,inf,b-1,c,d);
                reset(b-1,c);
                if(rk==1) printf("fuck\n");
                else printf("%d\n",query2(0,inf,b-1,c,rk-1));
			}
			if(a==5){
				reset(b-1,c);
                int rk=query1(0,inf,b-1,c,d+1);
                reset(b-1,c);
                int re=query2(0,inf,b-1,c,rk);
                if(re==-1) printf("fuck\n");
                else printf("%d\n",re);
			}
		}
	}return 0;
}

少女填坑中...

猜你喜欢

转载自blog.csdn.net/strangeDDDF/article/details/86915537