主席树求调
查看原帖
主席树求调
852295
Mr_Vatican楼主2022/11/5 17:31
#include <bits/stdc++.h>
using namespace std;
int n,m,root[100005],cnt=0;
struct node
{
	int tl,tr,deep,fa;
}tree[2000005];
int query(int p,int l,int r,int son)
{
	if(l==r)
		return p;
	int mid=(l+r)/2;
	if(son<=mid)
		return query(tree[p].tl,l,mid,son);
	else
		return query(tree[p].tr,mid+1,r,son);
}
int find(int p,int x)
{
	int id=query(p,1,n,x);
	if(x==tree[id].fa)
		return id;
	else
		return find(p,tree[id].fa);
}
void build(int &p,int l,int r) 
{
    p=++cnt;
    if(l==r)
	{
        tree[p].fa=l;
        tree[p].deep=1;
        return ;
    }
    int mid=(l+r)/2;
    build(tree[p].tl,l,mid);
    build(tree[p].tr,mid+1,r);
    return ;
}
void merge(int last,int &p,int l,int r,int fa,int son)
{
	if(l>son||r<son)
		return ;
	p=++cnt;
	tree[p]=tree[last];
	if(l==r)
	{
		tree[p].fa=fa;
		return ;
	}
	int mid=(l+r)/2;
	if(son<=mid)
		merge(tree[last].tl,tree[p].tl,l,mid,fa,son);
	else
		merge(tree[last].tr,tree[p].tr,mid+1,r,fa,son);
	return ;
}
void dep_add(int p,int l,int r,int add)
{
	if(l==r)
	{
		tree[p].deep++;
		return ;
	}
	int mid=(l+r)/2;
	if(p<=mid)
		dep_add(tree[p].tl,l,mid,add);
	else
		dep_add(tree[p].tr,mid+1,r,add);
	return ;
}
int main()
{
	scanf("%d%d",&n,&m);
	build(root[0],1,n);
	for(int i=1;i<=m;i++)
	{
		int ope,a,b,k;
		scanf("%d",&ope);
		if(ope==1)
		{
			scanf("%d%d",&a,&b);
			root[i]=root[i-1];
			int fa1=find(root[i],a);
			int fa2=find(root[i],b);
			if(tree[fa1].fa!=tree[fa2].fa)
			{
				if(tree[fa1].deep<tree[fa2].deep)
					swap(fa1,fa2);
				merge(root[i-1],root[i],1,n,tree[fa1].fa,tree[fa2].fa);
				if(tree[fa1].deep==tree[fa2].deep)
					dep_add(root[i],1,n,tree[fa1].fa);
			}
		}
		else if(ope==2)
		{
			scanf("%d",&k);
			root[i]=root[k];
		}
		else
		{
			scanf("%d%d",&a,&b);
			root[i]=root[i-1];
			int fa1=find(root[i],a),fa2=find(root[i],b);
			if(tree[fa1].fa==tree[fa2].fa)
				printf("1\n");
			else
				printf("0\n");
		}
	}
	return 0;
}
2022/11/5 17:31
加载中...