hdu 5002 Tree(LCT裸题)

题目链接:hdu 5002 Tree

题意:

给你一棵树,每个节点有个权值。

现在有四种操作

1. 删一条边加一条边,保证操作后还是一棵树。

2. 将一条链的节点的权值设为x.

3. 将一条链的节点的权值加上x.

4. 询问一条链的第二大权值,并且输出有多少个。

题解:

很裸的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 typedef pair<int,int>P;
  6 
  7 namespace LCT
  8 {
  9     const int N=1e5+7,inf=2e9+7;
 10     int f[N],son[N][2],val[N],tmp[N],sum[N],lazy[N],laop[N];
 11     int g[N],v[N*2],nxt[N*2],ed;bool rev[N];
 12     P mx[N][2],tp[10];
 13     void clear(int n)
 14     {
 15         F(i,1,n)f[i]=son[i][0]=son[i][1]=0;
 16         F(i,1,n)rev[i]=lazy[i]=laop[i]=g[i]=0;ed=0;
 17         F(i,1,n)mx[i][0]=mx[i][1]=P(-inf,0);
 18     }
 19     void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
 20     void build(int x=1){
 21         sum[x]=1,mx[x][0]=P(val[x],1);
 22         for(int i=g[x];i;i=nxt[i])
 23             if(!f[v[i]]&&v[i]!=1)f[v[i]]=x,build(v[i]);
 24     }
 25     bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
 26     void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;}
 27     void add(int x,int c,int op)
 28     {
 29         if(!x)return;
 30         if(op==2)
 31         {
 32             val[x]+=c,lazy[x]+=c;
 33             mx[x][0].first+=c;
 34             if(mx[x][1].first!=-inf)mx[x][1].first+=c;
 35         }
 36         else if(op==1)
 37         {
 38             val[x]=c,lazy[x]=c;
 39             mx[x][0]=P(c,sum[x]);
 40             mx[x][1]=P(-inf,0);
 41             laop[x]=1;
 42         }
 43         if(!laop[x])laop[x]=op;
 44     }
 45     void pb(int x){
 46         if(rev[x])rev1(son[x][0]),rev1(son[x][1]),rev[x]=0;
 47         if(laop[x])add(son[x][0],lazy[x],laop[x]),add(son[x][1],lazy[x],laop[x]),lazy[x]=laop[x]=0;
 48     }
 49     void up(int x){
 50         sum[x]=1;
 51         int ct=0;
 52         tp[ct=1]=P(val[x],1);
 53         if(son[x][0])
 54         {
 55            sum[x]+=sum[son[x][0]];
 56            F(i,0,1)tp[++ct]=mx[son[x][0]][i];
 57         }
 58         if(son[x][1])
 59         {
 60             sum[x]+=sum[son[x][1]];
 61             F(i,0,1)tp[++ct]=(mx[son[x][1]][i]);
 62         }
 63         sort(tp+1,tp+1+ct,greater<P>());
 64         int cnt=1;
 65         F(i,2,ct)
 66         {
 67             if(tp[i].first==tp[cnt].first)tp[cnt].second+=tp[i].second;
 68             else tp[++cnt]=tp[i];
 69         }
 70         mx[x][0]=tp[1];
 71         if(cnt>1)mx[x][1]=tp[2];
 72         else mx[x][1]=P(-inf,0);
 73     }
 74     void rotate(int x){
 75         int y=f[x],w=son[y][1]==x;
 76         son[y][w]=son[x][w^1];
 77         if(son[x][w^1])f[son[x][w^1]]=y;
 78         if(f[y]){
 79             int z=f[y];
 80             if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
 81         }
 82         f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
 83     }
 84     void splay(int x){
 85         int s=1,i=x,y;tmp[1]=i;
 86         while(!isroot(i))tmp[++s]=i=f[i];
 87         while(s)pb(tmp[s--]);
 88         while(!isroot(x)){
 89             y=f[x];
 90             if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
 91             rotate(x);
 92         }
 93         up(x);
 94     }
 95     void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y,up(x);}
 96     int root(int x){access(x);splay(x);while(son[x][0])x=son[x][0];return x;}
 97     void makeroot(int x){access(x);splay(x);rev1(x);}
 98     void link(int x,int y){makeroot(x);f[x]=y;access(x);}
 99     void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;up(x);}
100     void cut(int x,int y){makeroot(x);cutf(y);}
101     void update(int x,int y,int c,int op){makeroot(x),access(y),splay(y),add(y,c,op);}
102     P ask(int x,int y){makeroot(x);access(y);splay(y);return mx[y][1];}
103 }
104 using namespace LCT;
105 int t,n,m,c,a,b,x,y,cas;
106 
107 int main()
108 {
109     scanf("%d",&t);
110     while(t--)
111     {
112         scanf("%d%d",&n,&m);
113         clear(n);
114         F(i,1,n)scanf("%d",val+i);
115         F(i,2,n)
116         {
117             scanf("%d%d",&x,&y);
118             adg(x,y),adg(y,x);
119         }
120         build(),printf("Case #%d:\n",++cas);
121         F(i,1,m)
122         {
123             scanf("%d",&c);
124             if(c==1)
125             {
126                 scanf("%d%d%d%d",&x,&y,&a,&b);
127                 cut(x,y),link(a,b);
128             }
129             else if(c==2)
130             {
131                 scanf("%d%d%d",&a,&b,&x);
132                 update(a,b,x,1);
133             }
134             else if(c==3)
135             {
136                 scanf("%d%d%d",&a,&b,&x);
137                 update(a,b,x,2);
138             }
139             else
140             {
141                 scanf("%d%d",&a,&b);
142                 P ans=ask(a,b);
143                 if(ans.first==-inf)puts("ALL SAME");
144                 else printf("%d %d\n",ans.first,ans.second);
145             }
146 
147         }
148     }
149     return 0;
150 }
View Code

 

posted @ 2017-10-26 18:23  bin_gege  阅读(268)  评论(0编辑  收藏  举报