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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4010

    题意:一棵树,四种操作:

    (1)若x和y不在一棵树上,将x和y连边;

    (2)若x和y在一棵树上,将x变成树根,将y从x树上分离;

    (3)若x和y在一棵树上,将x到y路径上的所有值增加det;

    (4)若x和y在一棵树上,输出x到y路径上的最大值。

    思路:1操作用link维护,2操作用cut,34操作先split(x,y),然后对y做tag,并且记录路径的max值。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<string>
      6 #include<algorithm>
      7 int tot,go[600005],next[600005],first[300005];
      8 int ch[600005][2],rev[600005],tag[600005],q[600005];
      9 int st[600005],mx[600005],fa[600005],v[600005];
     10 bool pd(int x){
     11     return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
     12 }
     13 void insert(int x,int y){
     14     tot++;go[tot]=y;next[tot]=first[x];first[x]=tot;
     15 }
     16 void addedge(int x,int y){
     17     insert(x,y);insert(y,x);
     18 }
     19 void pushdown(int x){
     20     int l=ch[x][0],r=ch[x][1];
     21     if (rev[x]){
     22         rev[x]^=1;rev[l]^=1;rev[r]^=1;
     23         std::swap(ch[x][0],ch[x][1]);
     24     }
     25     if (tag[x]){
     26         if (l) tag[l]+=tag[x],v[l]+=tag[x],mx[l]+=tag[x];
     27         if (r) tag[r]+=tag[x],mx[r]+=tag[x],v[r]+=tag[x];
     28         tag[x]=0;
     29     }
     30 }
     31 void updata(int x){
     32     int l=ch[x][0],r=ch[x][1];
     33     mx[x]=std::max(v[x],std::max(mx[l],mx[r]));
     34 }
     35 void rotate(int x){
     36     int y=fa[x],z=fa[y],l,r;
     37     if (ch[y][0]==x) l=0;else l=1;r=l^1;
     38     if (!pd(y)){
     39         if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;
     40     }
     41     fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;
     42     ch[y][l]=ch[x][r];ch[x][r]=y;
     43     updata(y);updata(x);
     44 }
     45 void splay(int x){
     46     int top=0;st[++top]=x;
     47     for (int i=x;!pd(i);i=fa[i])
     48      st[++top]=fa[i];
     49     for (int i=top;i;i--)
     50      pushdown(st[i]);
     51     while (!pd(x)){
     52         int y=fa[x],z=fa[y];
     53         if (!pd(y)){
     54             if (ch[y][0]==x^ch[z][0]==y) rotate(x);
     55             else rotate(y);
     56         }
     57         rotate(x);
     58     }  
     59 }
     60 void access(int x){
     61     for (int t=0;x;t=x,x=fa[x]){
     62         splay(x);
     63         ch[x][1]=t;
     64         updata(x);
     65     }
     66 }
     67 void makeroot(int x){
     68     access(x);splay(x);rev[x]^=1;
     69 }
     70 void cut(int x,int y){
     71     makeroot(x);access(y);splay(y);ch[y][0]=fa[ch[y][0]]=0;updata(y);
     72 }
     73 void link(int x,int y){
     74     makeroot(x);
     75     fa[x]=y;
     76 }
     77 int find(int x){
     78     access(x);splay(x);
     79     while (ch[x][0]) x=ch[x][0];
     80     return x;
     81 }
     82 void add(int x,int y,int val){
     83     makeroot(x);access(y);splay(y);
     84     mx[y]+=val;v[y]+=val;tag[y]+=val;
     85 }
     86 int main(){
     87     int n,x,y,m,opt,w;
     88     while (scanf("%d",&n)!=EOF){
     89         mx[0]=-2000000000;
     90         for (int i=0;i<=n;i++) 
     91          mx[i]=tag[i]=rev[i]=v[i]=ch[i][0]=ch[i][1]=fa[i]=0;
     92         memset(first,0,sizeof first);tot=0;
     93         for (int i=1;i<n;i++){
     94          scanf("%d%d",&x,&y);
     95          addedge(x,y);
     96         }
     97         for (int i=1;i<=n;i++){
     98             scanf("%d",&v[i]);
     99             mx[i]=v[i];
    100         }
    101         int top=1;
    102         q[top]=1;
    103         for (int k=1;k<=top;k++){
    104             for (int i=first[q[k]];i;i=next[i]){
    105                 int pur=go[i];
    106                 if (pur==fa[q[k]]) continue;
    107                 fa[pur]=q[k];
    108                 q[++top]=pur;
    109             }
    110         }
    111         top=0;
    112         scanf("%d",&m);
    113         while (m--){
    114             scanf("%d",&opt);
    115             if (opt==1){
    116                 scanf("%d%d",&x,&y);
    117                 if (find(x)==find(y)) {puts("-1");continue;}
    118                 link(x,y);
    119             }
    120             else
    121             if (opt==2){
    122                 scanf("%d%d",&x,&y);
    123                 if (find(x)!=find(y)||x==y) {puts("-1");continue;}
    124                 cut(x,y);
    125             }
    126             else
    127             if (opt==3){
    128                 scanf("%d%d%d",&w,&x,&y);
    129                 if (find(x)!=find(y)){puts("-1");continue;}
    130                 add(x,y,w);
    131             }
    132             else
    133             if (opt==4)
    134             {
    135                 scanf("%d%d",&x,&y);
    136                 if (find(x)!=find(y)){
    137                     printf("-1
    ");
    138                     continue;
    139                 }
    140                 makeroot(x);access(y);splay(y);
    141                 printf("%d
    ",mx[y]);
    142             }
    143         }
    144         printf("
    ");
    145     }
    146 }
  • 相关阅读:
    solr 最佳实践
    DNS 域名解析过程
    mac 下 virtualbox 配置全网通
    搜索引擎使用技巧
    三叉搜索树
    双数组trie树的基本构造及简单优化
    基于回归-马尔科夫模型的客运量预测
    solr 常用命令
    PHP yield 分析,以及协程的实现,超详细版(上)
    C语言,简单计算器【上】
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5537899.html
Copyright © 2011-2022 走看看