• HDU4010 (动态树)


    Problem Query on The Trees

    题目大意

      给一棵树,有点权,要求维护4种操作。

      操作1:加一条边。  

      操作2:删一条边。  

      操作3:将一条路径上的点权增加w。  

      操作4:询问一条路径上的点权最大值。

    解题分析

      lct练习题

      ps:lct模板抄自黄学长。

    参考程序

      1 #include <map>
      2 #include <set>
      3 #include <stack>
      4 #include <queue>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <string>
      8 #include <vector>
      9 #include <cstdio>
     10 #include <cstdlib>
     11 #include <cstring>
     12 #include <cassert>
     13 #include <iostream>
     14 #include <algorithm>
     15 #pragma comment(linker,"/STACK:102400000,102400000")
     16 using namespace std;
     17 
     18 #define N 300008             
     19 #define M 50008    
     20 #define LL long long
     21 #define lson l,m,rt<<1
     22 #define rson m+1,r,rt<<1|1 
     23 #define clr(x,v) memset(x,v,sizeof(x));
     24 #define bitcnt(x) __builtin_popcount(x)
     25 #define rep(x,y,z) for (int x=y;x<=z;x++)
     26 #define repd(x,y,z) for (int x=y;x>=z;x--)
     27 const int mo  = 1000000007;
     28 const int inf = 0x3f3f3f3f;
     29 const int INF = 2000000000;
     30 /**************************************************************************/
     31 
     32 int val[N],c[N][2],fa[N],mx[N],tag[N],rev[N],lt[N],st[N];
     33 int n,q,sum;
     34 struct line{
     35     int u,v,nt;
     36 }eg[N*2];
     37 void addedge(int u,int v){
     38     eg[++sum]=(line){u,v,lt[u]};
     39     lt[u]=sum;
     40 }
     41 void init(){
     42     rep(i,1,n) val[i]=c[i][0]=c[i][1]=mx[i]=tag[i]=rev[i]=lt[i]=fa[i]=0;
     43     sum=1;
     44 }
     45 void dfs(int u){
     46     for (int i=lt[u];i;i=eg[i].nt){
     47         int v=eg[i].v;
     48         if (fa[v] || v==1) continue;
     49         fa[v]=u;
     50         dfs(v);
     51     }
     52 }
     53 bool isroot(int k){
     54     return c[fa[k]][0]!=k && c[fa[k]][1]!=k;
     55 }
     56 void pushup(int x){
     57     int l=c[x][0],r=c[x][1];
     58     mx[x]=max(max(mx[l],mx[r]),val[x]);
     59 }
     60 void pushdown(int x){
     61     int l=c[x][0],r=c[x][1];
     62     if (rev[x]){
     63         if (l) rev[l]^=1;
     64         if (r) rev[r]^=1;
     65         rev[x]^=1;
     66         swap(c[x][0],c[x][1]);
     67     }
     68     if (tag[x]){
     69         if (l) {tag[l]+=tag[x]; mx[l]+=tag[x], val[l]+=tag[x]; }
     70         if (r) {tag[r]+=tag[x]; mx[r]+=tag[x], val[r]+=tag[x]; }
     71         tag[x]=0;
     72     }
     73 }
     74 void rotate(int x){
     75     int y=fa[x],z=fa[y],l,r;
     76     if (c[y][0]==x) l=0; else l=1; r=l^1;
     77     if (!isroot(y)){
     78         if (c[z][0]==y) c[z][0]=x; else c[z][1]=x;
     79     }
     80     fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
     81     c[y][l]=c[x][r]; c[x][r]=y;
     82     pushup(y); pushup(x);
     83 }
     84 void splay(int x){
     85     int top=0; st[++top]=x;
     86     for (int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
     87     while (top) pushdown(st[top--]);
     88     while (!isroot(x)){
     89         int y=fa[x],z=fa[y];
     90         if (!isroot(y)){
     91             if (c[y][0]==x^c[z][0]==y) rotate(x);
     92             else rotate(y);
     93         }
     94         rotate(x);
     95     }
     96 }
     97 void access(int x){
     98     int t=0;
     99     while (x){
    100         splay(x);
    101         c[x][1]=t;
    102         pushup(x);            
    103         t=x; x=fa[x];
    104     }
    105 }
    106 int find(int u){
    107     access(u); splay(u);
    108     while (c[u][0]) u=c[u][0];
    109     return u;
    110 }
    111 bool judge(int u,int v){
    112     return find(u)==find(v);
    113 }
    114 void rever(int u){
    115     access(u); splay(u); rev[u]^=1;
    116 }
    117 void link(int u,int v){
    118     rever(u); fa[u]=v; 
    119 }
    120 void cut(int u,int v){
    121     rever(u); access(v); splay(v); fa[c[v][0]]=0; c[v][0]=0; pushup(v);
    122 }
    123 void add(int u,int v,int w){
    124     rever(u); access(v); splay(v); tag[v]+=w; mx[v]+=w; val[v]+=w;
    125 }
    126 void query(int u,int v){
    127     rever(u); access(v); splay(v); printf("%d
    ",mx[v]);
    128 }
    129 int main(){
    130     while (~scanf("%d",&n))
    131     {
    132         init();
    133         rep(i,1,n-1){
    134             int u,v;
    135             scanf("%d%d",&u,&v);
    136             addedge(u,v); addedge(v,u);
    137         }
    138         rep(i,1,n){
    139             int x;
    140             scanf("%d",&x);
    141             val[i]=mx[i]=x;
    142         }
    143         dfs(1);
    144         scanf("%d",&q);
    145         while (q--){
    146             int x,u,v,w;
    147             scanf("%d",&x);
    148             if (x==1){
    149                 scanf("%d %d",&u,&v);        
    150                 if (!judge(u,v)) link(u,v); else puts("-1");
    151             }
    152             if (x==2){
    153                 scanf("%d %d",&u,&v);        
    154                 if (judge(u,v) && u!=v) cut(u,v); else puts("-1");
    155             }
    156             if (x==3){
    157                 scanf("%d %d %d",&w,&u,&v);
    158                 if (judge(u,v)) add(u,v,w);    else puts("-1");
    159             }
    160             if (x==4){
    161                 scanf("%d %d",&u,&v);        
    162                 if (judge(u,v)) query(u,v); else puts("-1");
    163             }
    164         }
    165         printf("
    ");
    166     }
    167 }
    View Code
  • 相关阅读:
    HDU 1978 How many ways
    hdu 1966 Pie
    hdu 1966 Pie
    HDU 1896 Stones
    HDU 1896 Stones
    hdu 1278 逃离迷宫
    hdu 1278 逃离迷宫
    HDU 2548 A strange lift
    HDU 2548 A strange lift
    PHP 错误与异常 笔记与总结(10)错误处理器测试
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5829164.html
Copyright © 2020-2023  润新知