• 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:
    ",++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
    ",ans.first,ans.second);
    145             }
    146 
    147         }
    148     }
    149     return 0;
    150 }
    View Code
  • 相关阅读:
    MoveWindow() SetWindowPos()的区别与联系
    SEO搜索引擎优化基础
    Windows核心编程小结1
    STL学习笔记8 -- 函数对象
    Java关于反射
    多线程处理慢sql查询小笔记~
    前端小菜鸡使用Vue+Element笔记(二)
    前端小菜鸡使用Vue+Element笔记(一)
    Hive/hbase/sqoop的基本使用教程~
    Hive/Hbase/Sqoop的安装教程
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7738300.html
Copyright © 2020-2023  润新知