• 【BZOJ4736】温暖会指引我们前行(Link-Cut Tree)


    【BZOJ4736】温暖会指引我们前行(Link-Cut Tree)

    ##题面
    

    神TM题面是UOJ的

    题解

    LCT傻逼维护最大生成树
    不会的可以去做一做魔法森林

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAX 700000
    #define lson (t[x].ch[0])
    #define rson (t[x].ch[1])
    #define rg register
    inline int read()
    {
    	rg int x=0,t=1;rg char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return x*t;
    }
    struct Node
    {
    	int ch[2],ff;
    	int rev;
    	int sum,ma,v,r;
    }t[MAX];
    int S[MAX],top,n,m;
    void pushup(int x)
    {
    	t[x].sum=t[lson].sum+t[rson].sum+t[x].v;
    	t[x].ma=(t[t[lson].ma].r>t[t[rson].ma].r)?t[rson].ma:t[lson].ma;
    	if(t[x].r<t[t[x].ma].r)t[x].ma=x;
    }
    inline bool isroot(int x){return t[t[x].ff].ch[0]!=x&&t[t[x].ff].ch[1]!=x;}
    inline void rotate(int x)
    {
    	rg int y=t[x].ff,z=t[y].ff;
    	rg int k=t[y].ch[1]==x;
    	if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
    	t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
    	t[x].ch[k^1]=y;t[y].ff=x;
    	pushup(y);pushup(x);
    }
    inline void pushdown(int x)
    {
    	if(!t[x].rev)return;
    	t[lson].rev^=1;t[rson].rev^=1;
    	t[x].rev^=1;
    	swap(lson,rson);
    }
    void Splay(int x)
    {
    	S[top=1]=x;
    	for(int i=x;!isroot(i);i=t[i].ff)S[++top]=t[i].ff;
    	while(top)pushdown(S[top--]);
    	while(!isroot(x))
    	{
    		int y=t[x].ff,z=t[y].ff;
    		if(!isroot(y))
    			(t[y].ch[1]==x)^(t[z].ch[1]==y)?rotate(x):rotate(y);
    		rotate(x);
    	}
    }
    void access(int x){for(int y=0;x;y=x,x=t[x].ff)Splay(x),t[x].ch[1]=y,pushup(x);}
    void makeroot(int x){access(x);Splay(x);t[x].rev^=1;}
    void split(int x,int y){makeroot(x);access(y);Splay(y);}
    void link(int x,int y){makeroot(x);t[x].ff=y;}
    void cut(int x,int y){split(x,y);t[x].ff=t[y].ch[0]=0;pushup(y);}
    int findroot(int x){access(x);Splay(x);while(lson)x=lson;return x;}
    int main()
    {
    	n=read();m=read();
    	for(rg int i=0;i<=n;++i)t[i].r=1e9;
    	rg char ch[10];
    	while(m--)
    	{
    		scanf("%s",ch);
    		if(ch[0]=='f')
    		{
    			rg int id=read()+1,u=read()+1,v=read()+1,tmp=read(),len=read();
    			t[id+n].r=tmp;t[id+n].v=len;
    			if(findroot(u)!=findroot(v))link(u,id+n),link(v,id+n);//未联通
    			else
    			{
    				split(u,v);
    				if(t[t[v].ma].r<tmp)
    				{
    					rg int ss=t[v].ma;
    					cut(u,ss);cut(v,ss);
    					link(u,id+n);link(v,id+n);
    				}
    			}
    		}
    		else if(ch[0]=='m')
    		{
    			rg int u=read()+1,v=read()+1;
    			if(findroot(u)!=findroot(v))puts("-1");
    			else split(u,v),printf("%d
    ",t[v].sum);
    		}
    		else
    		{
    			rg int id=read()+1,len=read();
    			makeroot(id+n);t[id+n].v=len;pushup(id+n);
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    差分约束系统详解
    AC自动机详解
    KMP算法详解
    ST算法详解
    Trie详解
    欧拉路径详解
    树上差分详解
    LCA详解
    树链剖分详解
    树的直径详解
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8178649.html
Copyright © 2020-2023  润新知