码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 4010 Query on The Trees(LCT裸题)

时间:2017-10-18 23:08:56      阅读:259      评论:0      收藏:0      [点我收藏+]

标签:++   open   ref   memset   color   lazy   lin   一个   target   

题目链接:hdu 4010 Query on The Trees

题意:

给你一棵树,有4种操作。

1 连接x,y.

2 断开x,y.

3 将x到y这条路径加上一个值w.

4 询问x到y这条路径的最大值.

题解:

LCT必做题,全是LCT操作。

技术分享
  1 #include<bits/stdc++.h>
  2 #define F(i,a,b) for(int i=a;i<=b;i++)
  3 #define mst(a,b) memset(a,b,sizeof(a))
  4 using namespace std;
  5 
  6 namespace LCT
  7 {
  8     const int N=1e5+7;
  9     int f[N],son[N][2],val[N],sum[N],tmp[N],lazy[N];
 10     int g[N],v[N*2],nxt[N*2],ed;bool rev[N];
 11     void clear(int n)
 12     {
 13         F(i,1,n)f[i]=son[i][0]=son[i][1]=0;
 14         F(i,1,n)rev[i]=lazy[i]=g[i]=0;ed=0;
 15     }
 16     void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
 17     void build(int x=1){
 18         sum[x]=val[x];
 19         for(int i=g[x];i;i=nxt[i])
 20             if(!f[v[i]]&&v[i]!=1)f[v[i]]=x,build(v[i]);    
 21     }
 22     bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
 23     void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;}
 24     void add(int x,int c){if(!x)return;sum[x]+=c,val[x]+=c,lazy[x]+=c;}
 25     void pb(int x){
 26         if(rev[x])rev1(son[x][0]),rev1(son[x][1]),rev[x]=0;
 27         if(lazy[x])add(son[x][0],lazy[x]),add(son[x][1],lazy[x]),lazy[x]=0;
 28     }
 29     void up(int x){
 30         sum[x]=val[x];
 31         if(son[x][0])sum[x]=max(sum[son[x][0]],sum[x]);
 32         if(son[x][1])sum[x]=max(sum[son[x][1]],sum[x]);
 33     }
 34     void rotate(int x){
 35         int y=f[x],w=son[y][1]==x;
 36         son[y][w]=son[x][w^1];
 37         if(son[x][w^1])f[son[x][w^1]]=y;
 38         if(f[y]){
 39             int z=f[y];
 40             if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
 41         }
 42         f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
 43     }
 44     void splay(int x){
 45         int s=1,i=x,y;tmp[1]=i;
 46         while(!isroot(i))tmp[++s]=i=f[i];
 47         while(s)pb(tmp[s--]);
 48         while(!isroot(x)){
 49             y=f[x];
 50             if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
 51             rotate(x);
 52         }
 53         up(x);
 54     }
 55     void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y,up(x);}
 56     int root(int x){access(x);splay(x);while(son[x][0])x=son[x][0];return x;}
 57     void makeroot(int x){access(x);splay(x);rev1(x);}
 58     void link(int x,int y){makeroot(x);f[x]=y;access(x);}
 59     void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;up(x);}
 60     void cut(int x,int y){makeroot(x);cutf(y);}
 61     void update(int x,int y,int c){makeroot(x),access(y),splay(y),add(y,c);}
 62     int ask(int x,int y){makeroot(x);access(y);splay(y);return sum[y];}
 63 }
 64 
 65 int n,x,y,z,q,op;
 66 
 67 int main()
 68 {
 69     while(~scanf("%d",&n))
 70     {
 71         LCT::clear(n);
 72         F(i,2,n)
 73         {
 74             scanf("%d%d",&x,&y);
 75             LCT::adg(x,y),LCT::adg(y,x);
 76         }
 77         F(i,1,n)scanf("%d",LCT::val+i);
 78         LCT::build();
 79         scanf("%d",&q);
 80         while(q--)
 81         {
 82             scanf("%d",&op);
 83             if(op==1)//连接x,y
 84             {
 85                 scanf("%d%d",&x,&y);
 86                 if(LCT::root(x)!=LCT::root(y))
 87                     LCT::link(x,y);
 88                 else puts("-1");
 89             }
 90             else if(op==2)//断开x,y
 91             {
 92                 scanf("%d%d",&x,&y);
 93                 if(LCT::root(x)==LCT::root(y)&&x!=y)
 94                     LCT::cut(x,y);
 95                 else puts("-1");
 96             }
 97             else if(op==3)//这条链加值
 98             {
 99                 scanf("%d%d%d",&z,&x,&y);
100                 if(LCT::root(x)==LCT::root(y))
101                     LCT::update(x,y,z);
102                 else puts("-1");
103             }
104             else  //询问这条链
105             {
106                 scanf("%d%d",&x,&y);
107                 if(LCT::root(x)==LCT::root(y))
108                     printf("%d\n",LCT::ask(x,y));
109                 else puts("-1");
110             }
111         }
112         puts("");
113     }
114     return 0;
115 }
View Code

 

hdu 4010 Query on The Trees(LCT裸题)

标签:++   open   ref   memset   color   lazy   lin   一个   target   

原文地址:http://www.cnblogs.com/bin-gege/p/7689431.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!