zoukankan      html  css  js  c++  java
  • 动态树(LCT):HDU 4010 Query on The Trees

    Query on The Trees

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
    Total Submission(s): 4002    Accepted Submission(s): 1749


    Problem Description
    We have met so many problems on the tree, so today we will have a query problem on a set of trees. 
    There are N nodes, each node will have a unique weight Wi. We will have four kinds of operations on it and you should solve them efficiently. Wish you have fun! 

     
    Input
    There are multiple test cases in our dataset. 
    For each case, the first line contains only one integer N.(1 ≤ N ≤ 300000) The next N‐1 lines each contains two integers x, y which means there is an edge between them. It also means we will give you one tree initially. 
    The next line will contains N integers which means the weight Wi of each node. (0 ≤ Wi ≤ 3000) 
    The next line will contains an integer Q. (1 ≤ Q ≤ 300000) The next Q lines will start with an integer 1, 2, 3 or 4 means the kind of this operation. 
    1. Given two integer x, y, you should make a new edge between these two node x and y. So after this operation, two trees will be connected to a new one. 
    2. Given two integer x, y, you should find the tree in the tree set who contain node x, and you should make the node x be the root of this tree, and then you should cut the edge between node y and its parent. So after this operation, a tree will be separate into two parts. 
    3. Given three integer w, x, y, for the x, y and all nodes between the path from x to y, you should increase their weight by w. 
    4. Given two integer x, y, you should check the node weights on the path between x and y, and you should output the maximum weight on it. 
     
    Output
    For each query you should output the correct answer of it. If you find this query is an illegal operation, you should output ‐1. 
    You should output a blank line after each test case.
     
    Sample Input
    5 1 2 2 4 2 5 1 3 1 2 3 4 5 6 4 2 3 2 1 2 4 2 3 1 3 5 3 2 1 4 4 1 4
     
    Sample Output
    3 -1 7
    Hint
    We define the illegal situation of different operations: In first operation: if node x and y belong to a same tree, we think it's illegal. In second operation: if x = y or x and y not belong to a same tree, we think it's illegal. In third operation: if x and y not belong to a same tree, we think it's illegal. In fourth operation: if x and y not belong to a same tree, we think it's illegal.
     
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 
      5 using namespace std;
      6 const int MAXN=300010;
      7 int fir[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt;
      8 int Max[MAXN],fa[MAXN],ch[MAXN][2],flip[MAXN],add[MAXN],key[MAXN];
      9 bool rt[MAXN]; 
     10 
     11 void Push_up(int p)
     12 {
     13     Max[p]=max(key[p],max(Max[ch[p][0]],Max[ch[p][1]]));
     14 }
     15 
     16 void Add(int p,int d)
     17 {
     18     if(!p)return;
     19     key[p]+=d;
     20     Max[p]+=d;
     21     add[p]+=d;
     22 }
     23 void Flip(int p)
     24 {
     25     if(!p)return;
     26     swap(ch[p][0],ch[p][1]);
     27     flip[p]^=1;
     28 }
     29 void Push_down(int p)
     30 {
     31     if(add[p]){
     32         Add(ch[p][0],add[p]);
     33         Add(ch[p][1],add[p]);
     34         add[p]=0;
     35     }
     36     if(flip[p]){
     37         Flip(ch[p][0]);
     38         Flip(ch[p][1]);
     39         flip[p]=0;
     40     }
     41 }
     42 
     43 void Rotate(int x)
     44 {
     45     int y=fa[x],g=fa[y],c=ch[y][1]==x;
     46     ch[y][c]=ch[x][c^1];fa[ch[y][c]]=y;
     47     ch[x][c^1]=y;fa[y]=x;fa[x]=g;
     48     if(rt[y])
     49         rt[y]=false,rt[x]=true;
     50     else
     51         ch[g][ch[g][1]==y]=x;
     52     Push_up(y);        
     53 }
     54 
     55 void P(int p)
     56 {
     57     if(!rt[p])P(fa[p]);
     58     Push_down(p);
     59 }
     60 
     61 void Splay(int x)
     62 {
     63     P(x);
     64     for(int y=fa[x];!rt[x];Rotate(x),y=fa[x])
     65         if(!rt[y])
     66             Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x);
     67     Push_up(x);        
     68 }
     69 
     70 bool Judge(int x,int y)
     71 {
     72     while(fa[x])x=fa[x];
     73     while(fa[y])y=fa[y];
     74     return x==y;
     75 }
     76 
     77 void Access(int x)
     78 {
     79     int y=0;
     80     while(x)
     81     {
     82         Splay(x);
     83         rt[ch[x][1]]=true;
     84         rt[ch[x][1]=y]=false;
     85         Push_up(x);
     86         x=fa[y=x];
     87     }
     88 }
     89 void Lca(int &x,int &y)
     90 {
     91     Access(y);y=0;
     92     while(true)
     93     {
     94         Splay(x);
     95         if(!fa[x])return;
     96         rt[ch[x][1]]=true;
     97         rt[ch[x][1]=y]=false;
     98         Push_up(x);
     99         x=fa[y=x];
    100     }
    101 }
    102 void Make_root(int x)
    103 {
    104     Access(x);
    105     Splay(x);
    106     Flip(x);
    107 } 
    108 
    109 void Link(int x,int y)
    110 {
    111     if(Judge(x,y)){
    112         printf("-1
    ");
    113         return;
    114     }
    115     Make_root(x);
    116     Splay(x);
    117     fa[x]=y;
    118 }
    119 
    120 void Cut(int x,int y)
    121 {
    122     if(x==y||!Judge(x,y)){
    123         printf("-1
    ");
    124         return;
    125     }
    126     Make_root(x);
    127     Splay(y);
    128     fa[ch[y][0]]=fa[y];
    129     fa[y]=0;
    130     rt[ch[y][0]]=true;
    131     ch[y][0]=0;
    132     Push_up(y);
    133 }
    134 
    135 void Change(int x,int y,int d)
    136 {
    137     if(!Judge(x,y)){
    138         printf("-1
    ");
    139         return;
    140     }
    141     Lca(x,y);
    142     Add(ch[x][1],d);
    143     Add(y,d);
    144     key[x]+=d;
    145     Push_up(x);
    146 }
    147 
    148 void Query(int x,int y)
    149 {
    150     if(!Judge(x,y)){
    151         printf("-1
    ");
    152         return;
    153     }
    154     Lca(x,y);
    155     printf("%d
    ",max(key[x],max(Max[ch[x][1]],Max[y])));
    156 }
    157 
    158 void addedge(int a,int b)
    159 {
    160     nxt[++cnt]=fir[a];to[cnt]=b;fir[a]=cnt;
    161 }
    162 
    163 void DFS(int node,int pre)
    164 {
    165     for(int i=fir[node];i;i=nxt[i])
    166         if(to[i]!=pre){
    167             fa[to[i]]=node;
    168             DFS(to[i],node);
    169         }
    170 }
    171 void Init()
    172 {
    173     memset(fir,0,sizeof(fir));
    174     memset(ch,0,sizeof(ch));
    175     memset(fa,0,sizeof(fa));
    176     memset(rt,-1,sizeof(rt));
    177     memset(flip,0,sizeof(flip));
    178     memset(add,0,sizeof(add));
    179     cnt=0;Max[0]=-2100000000;
    180 }
    181 int main()
    182 {
    183     int Q,n,x,y,d,k;
    184     while(~scanf("%d",&n))
    185     {
    186         Init();
    187         for(int i=1;i<n;i++){
    188             scanf("%d%d",&x,&y);
    189             addedge(x,y);
    190             addedge(y,x);
    191         }
    192         for(int i=1;i<=n;i++){
    193             scanf("%d",&key[i]);
    194             Max[i]=key[i];
    195         }
    196         DFS(1,1);
    197         scanf("%d",&Q);
    198         while(Q--)
    199         {
    200             scanf("%d",&k);
    201             if(k==1){
    202                 scanf("%d%d",&x,&y);
    203                 Link(x,y);
    204             }
    205             else if(k==2){
    206                 scanf("%d%d",&x,&y);
    207                 Cut(x,y);
    208             }
    209             else if(k==3){
    210                 scanf("%d%d%d",&d,&x,&y);
    211                 Change(x,y,d);
    212             }
    213             else if(k==4){
    214                 scanf("%d%d",&x,&y);
    215                 Query(x,y);
    216             }
    217         }
    218         printf("
    ");
    219     }
    220     return 0;
    221 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    java中Logger.getLogger(Test.class),即log4日志的使用
    System.getProperty()方法大全 (转载)
    常用MySQL函数
    MYSQL常用命令(转载)
    Oracle中与日期时间有关的运算函数
    R
    珍惜现在,感恩生活 多重背包
    Piggy-Bank 完全背包
    骨骼收集器01背包
    D
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5211517.html
Copyright © 2011-2022 走看看