zoukankan      html  css  js  c++  java
  • hdu 4010 动态树 @

    kuangbin模板题,看起来十分高大上

      1 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2013-9-4 0:13:15
      4 File Name     :HDU4010.cpp
      5 ************************************************ */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 #include <time.h>
     19 using namespace std;
     20 //动态维护一组森林,要求支持一下操作:
     21 //link(a,b) : 如果a,b不在同一颗子树中,则通过在a,b之间连边的方式,连接这两颗子树
     22 //cut(a,b)  : 如果a,b在同一颗子树中,且a!=b,则将a视为这颗子树的根以后,切断b与其父亲结点的连接
     23 //ADD(a,b,w): 如果a,b在同一颗子树中,则将a,b之间路径上所有点的点权增加w
     24 //query(a,b): 如果a,b在同一颗子树中,返回a,b之间路径上点权的最大值
     25 const int MAXN = 300010;
     26 int ch[MAXN][2],pre[MAXN],key[MAXN];
     27 int add[MAXN],rev[MAXN],Max[MAXN];
     28 bool rt[MAXN];
     29 
     30 void Update_Add(int r,int d)
     31 {
     32     if(!r)return;
     33     key[r] += d;
     34     add[r] += d;
     35     Max[r] += d;
     36 }
     37 void Update_Rev(int r)
     38 {
     39     if(!r)return;
     40     swap(ch[r][0],ch[r][1]);
     41     rev[r] ^= 1;
     42 }
     43 void push_down(int r)
     44 {
     45     if(add[r])
     46     {
     47         Update_Add(ch[r][0],add[r]);
     48         Update_Add(ch[r][1],add[r]);
     49         add[r] = 0;
     50     }
     51     if(rev[r])
     52     {
     53         Update_Rev(ch[r][0]);
     54         Update_Rev(ch[r][1]);
     55         rev[r] = 0;
     56     }
     57 }
     58 void push_up(int r)
     59 {
     60     Max[r] = max(max(Max[ch[r][0]],Max[ch[r][1]]),key[r]);
     61 }
     62 void Rotate(int x)
     63 {
     64     int y = pre[x], kind = ch[y][1]==x;
     65     ch[y][kind] = ch[x][!kind];
     66     pre[ch[y][kind]] = y;
     67     pre[x] = pre[y];
     68     pre[y] = x;
     69     ch[x][!kind] = y;
     70     if(rt[y])
     71         rt[y] = false, rt[x] = true;
     72     else
     73         ch[pre[x]][ch[pre[x]][1]==y] = x;
     74     push_up(y);
     75 }
     76 //P函数先将根结点到r的路径上所有的结点的标记逐级下放
     77 void P(int r)
     78 {
     79     if(!rt[r])P(pre[r]);
     80     push_down(r);
     81 }
     82 void Splay(int r)
     83 {
     84     P(r);
     85     while( !rt[r] )
     86     {
     87         int f = pre[r], ff = pre[f];
     88         if(rt[f])
     89             Rotate(r);
     90         else if( (ch[ff][1]==f)==(ch[f][1]==r) )
     91             Rotate(f), Rotate(r);
     92         else
     93             Rotate(r), Rotate(r);
     94     }
     95     push_up(r);
     96 }
     97 int Access(int x)
     98 {
     99     int y = 0;
    100     for( ; x ; x = pre[y=x])
    101     {
    102         Splay(x);
    103         rt[ch[x][1]] = true, rt[ch[x][1]=y] = false;
    104         push_up(x);
    105     }
    106     return y;
    107 }
    108 //判断是否是同根(真实的树,非splay)
    109 bool judge(int u,int v)
    110 {
    111     while(pre[u]) u = pre[u];
    112     while(pre[v]) v = pre[v];
    113     return u == v;
    114 }
    115 //使r成为它所在的树的根
    116 void mroot(int r)
    117 {
    118     Access(r);
    119     Splay(r);
    120     Update_Rev(r);
    121 }
    122 //调用后u是原来u和v的lca,v和ch[u][1]分别存着lca的2个儿子
    123 //(原来u和v所在的2颗子树)
    124 void lca(int &u,int &v)
    125 {
    126     Access(v), v = 0;
    127     while(u)
    128     {
    129         Splay(u);
    130         if(!pre[u])return;
    131         rt[ch[u][1]] = true;
    132         rt[ch[u][1]=v] = false;
    133         push_up(u);
    134         u = pre[v = u];
    135     }
    136 }
    137 void link(int u,int v)
    138 {
    139     if(judge(u,v))
    140     {
    141         puts("-1");
    142         return;
    143     }
    144     mroot(u);
    145     pre[u] = v;
    146 }
    147 //使u成为u所在树的根,并且v和它父亲的边断开 
    148 void cut(int u,int v)
    149 {
    150     if(u == v || !judge(u,v))
    151     {
    152         puts("-1");
    153         return;
    154     }
    155     mroot(u);
    156     Splay(v);
    157     pre[ch[v][0]] = pre[v];
    158     pre[v] = 0;
    159     rt[ch[v][0]] = true;
    160     ch[v][0] = 0;
    161     push_up(v);
    162 }
    163 void ADD(int u,int v,int w)
    164 {
    165     if(!judge(u,v))
    166     {
    167         puts("-1");
    168         return;
    169     }
    170     lca(u,v);
    171     Update_Add(ch[u][1],w);
    172     Update_Add(v,w);
    173     key[u] += w;
    174     push_up(u);
    175 }
    176 void query(int u,int v)
    177 {
    178     if(!judge(u,v))
    179     {
    180         puts("-1");
    181         return;
    182     }
    183     lca(u,v);
    184     printf("%d
    ",max(max(Max[v],Max[ch[u][1]]),key[u]));
    185 }
    186 
    187 struct Edge
    188 {
    189     int to,next;
    190 }edge[MAXN*2];
    191 int head[MAXN],tot;
    192 void addedge(int u,int v)
    193 {
    194     edge[tot].to = v;
    195     edge[tot].next = head[u];
    196     head[u] = tot++;
    197 }
    198 void dfs(int u)
    199 {
    200     for(int i = head[u];i != -1; i = edge[i].next)
    201     {
    202         int v = edge[i].to;
    203         if(pre[v] != 0)continue;
    204         pre[v] = u;
    205         dfs(v);
    206     }
    207 }
    208 
    209 int main()
    210 {
    211     //freopen("in.txt","r",stdin);
    212     //freopen("out.txt","w",stdout);
    213     int n,q,u,v;
    214     while(scanf("%d",&n) == 1)
    215     {
    216         tot = 0;
    217         for(int i = 0;i <= n;i++)
    218         {
    219             head[i] = -1;
    220             pre[i] = 0;
    221             ch[i][0] = ch[i][1] = 0;
    222             rev[i] = 0;
    223             add[i] = 0;
    224             rt[i] = true;
    225         }
    226         Max[0] = -2000000000;
    227         for(int i = 1;i < n;i++)
    228         {
    229             scanf("%d%d",&u,&v);
    230             addedge(u,v);
    231             addedge(v,u);
    232         }
    233         for(int i = 1;i <= n;i++)
    234         {
    235             scanf("%d",&key[i]);
    236             Max[i] = key[i];
    237         }
    238         scanf("%d",&q);
    239         pre[1] = -1;
    240         dfs(1);
    241         pre[1] = 0;
    242         int op;
    243         while(q--)
    244         {
    245             scanf("%d",&op);
    246             if(op == 1)
    247             {
    248                 int x,y;
    249                 scanf("%d%d",&x,&y);
    250                 link(x,y);
    251             }
    252             else if(op == 2)
    253             {
    254                 int x,y;
    255                 scanf("%d%d",&x,&y);
    256                 cut(x,y);
    257             }
    258             else if(op == 3)
    259             {
    260                 int w,x,y;
    261                 scanf("%d%d%d",&w,&x,&y);
    262                 ADD(x,y,w);
    263             }
    264             else
    265             {
    266                 int x,y;
    267                 scanf("%d%d",&x,&y);
    268                 query(x,y);
    269             }
    270         }
    271         printf("
    ");
    272     }
    273     return 0;
    274 }
  • 相关阅读:
    RTMP协议Web直播点播系统EasyDSS视频平台解决无法获取指定时间快照问题
    在线教育web无插件点播平台EasyDSS在上传部分点播文件出现无法观看问题如何修复?
    RTMP协议Web直播点播服务平台EasyDSS增加获取录像指定时间的m3u8播放地址
    RTMP协议视频平台EasyDSS编译过程中Go语言异步信息处理设计与实现
    在线课堂web无插件直播点播平台EasyDSS播放指定时间段的录像报404是什么原因?
    推流直播如何通过EasyDSS推流将内网EasyGBS视频流推到公网直播间进行直播?
    RTMP协议视频平台EasyDSS开发中如何通过Go语言 gorm 框架钩子函数精简代码?
    POJ1740 A New Stone Game 博弈论基础题 男人8题
    HDU1847 博弈论 水题
    POJ 2763 Housewife Wind LCA基础题
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4687728.html
Copyright © 2011-2022 走看看