动态树

#include <cstdio>
#include <iostream>
#include<cstring>
using namespace std;
#define N 300010
const int M=2e5+10;
const int INF=1<<30;

struct Node{
	Node *p,*ch[2];
	int rev;
	int val,add;
	int l,r;
	int sz;
}node[N],*null;
int n_cnt;

void newnode(int w)
{
    Node* cur=&node[n_cnt++];
	cur->p=cur->ch[0]=cur->ch[1]=null;
	cur->add=-1;
	cur->val=cur->l=cur->r=w;
	cur->rev=0;
	cur->sz=1;
}

void init()
{
	null=node;
	null->p=null->ch[0]=null->ch[1]=null;
	null->add=-1;
	null->val=-1;null->l=null->r=-1;
	null->sz=0;
	null->rev=0;
	n_cnt=1;
}

struct dynamictree
{
	bool isroot(Node *x)//判根
	{
		return x->p==null || x->p->ch[0]!=x && x->p->ch[1]!=x;
	}
	void lazy(Node *x,int w)
	{
	    x->add=x->val=x->l=x->r=w;x->sz=1;
	}
	void flip(Node *x)
	{
	    x->rev^=1;
	    swap(x->ch[0],x->ch[1]);
	    swap(x->l,x->r);
	}
	void pushup(Node *x)
	{
		x->sz=1;
		if(x->ch[0]!=null)
        {
            x->l=x->ch[0]->l;
            x->sz+=x->ch[0]->sz;
            if(x->val==x->ch[0]->r)
            {
                x->sz--;
            }
        }
		else x->l=x->val;
		if(x->ch[1]!=null)
        {
            x->r=x->ch[1]->r;
            x->sz+=x->ch[1]->sz;
            if(x->val==x->ch[1]->l)
            {
                x->sz--;
            }
        }
		else x->r=x->val;
	}
	void pushdown(Node *x)
	{
		if(x==null) return;
        if(x->add!=-1)
		{
			if(x->ch[0]!=null)lazy(x->ch[0],x->add);
			if(x->ch[1]!=null)lazy(x->ch[1],x->add);
			x->add=-1;
		}
		if(x->rev)
		{
			x->rev=0;
			if(x->ch[0]!=null)flip(x->ch[0]);
			if(x->ch[1]!=null)flip(x->ch[1]);
		}
	}
	void rotate(Node *x,int f)
	{
	    Node *y=x->p;
	    pushdown(y);pushdown(x);
		y->ch[!f]=x->ch[f];
		if(x->ch[f]!=null) x->ch[f]->p=y;
		x->p=y->p;
		if(!isroot(y))
		{
			y->p->ch[y==y->p->ch[1]]=x;
		}
		x->ch[f]=y;
		y->p=x;
		pushup(y);
	}
	//找到链的根
	void splay(Node *x)
	{
        pushdown(x);
		while (!isroot(x))
		{
			Node *y=x->p;
			if(isroot(y)) rotate(x,x==y->ch[0]);
			else
			{
				int f=y->p->ch[0]==y;
				if(y->ch[f]==x) rotate(x,!f);
				else rotate(y,f);
				rotate(x,f);
			}
		}
		pushup(x);
	}
	///找到所在树的树根
	Node *access(Node *u)
	{
		Node *v=null;
		while (u!=null)
		{
			splay(u);
			u->ch[1]=v;
			pushup(u);
			v=u;
			u=u->p;
		}
		return v;
	}
	Node *link(Node *u,Node *v)//合并
	{
		access(u);
		splay(u);
		flip(u);
		u->p=v;
	}
	void makeroot(Node *x)//换根
	{
		access(x);
		splay(x);
		flip(x);
	}
	Node *getroot(Node *x)//找根
	{
		access(x);
		splay(x);
		while(x->ch[0]!=null)x=x->ch[0];
		return x;
	}
	bool queryuv(Node *u,Node *v)//判断是否在同一子树
	{
		while (u->p!=null) u=u->p;
		while (v->p!=null) v=v->p;
		return u==v;
	}
	void dfs(Node *x)
	{
	    if(x==null)return ;
	    pushdown(x);
	    dfs(x->ch[0]);
	    printf("%d ",x->val);
	    dfs(x->ch[1]);
	}
}spt;

int n,m,u,v,w;
char ss[20];
int main ()
{
   while (scanf("%d%d",&n,&m)!=EOF)
	{
		init();
		for(int i=1;i<=n;i++)
        {
            int a;scanf("%d",&a);
            newnode(a);
        }
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            spt.link(node+u,node+v);
        }
		for(int i=1;i<=m;i++)
		{
			scanf("%s",ss);
			if(ss[0]=='Q')
			{
			    int a,b;scanf("%d%d",&a,&b);
			    spt.makeroot(node+a);
			    spt.access(node+b);
			    spt.splay(node+b);
			    printf("%d-%d\n",i-1,node[b].sz);
			}
			else
			{
			    int a,b,c;scanf("%d%d%d",&a,&b,&c);
			    spt.makeroot(node+a);
			    spt.access(node+b);
			    spt.splay(node+b);
			    spt.lazy(node+b,c);
			}
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值