zoukankan      html  css  js  c++  java
  • [CodeChef-ANUDTQ] Dynamic Trees and Queries

    类似维护括号序列,给每个点建两个点,然后所有操作都能轻松支持了。注意sum和lastans是long long。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
     5 typedef long long ll;
     6 using namespace std;
     7 
     8 const int N=400010;
     9 ll ans,sm[N];
    10 int n,nd,tim,rt,op,x,y,m,cnt,a[N],tag[N];
    11 int v[N],f[N],L[N],R[N],sz[N],c[N][2],h[N],to[N],nxt[N];
    12 
    13 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
    14 
    15 void dfs(int x,int fa){
    16     L[x]=++tim; v[tim]=a[x];
    17     For(i,x) if ((k=to[i])!=fa) dfs(k,x);
    18     R[x]=++tim; v[tim]=a[x];
    19 }
    20 
    21 void upd(int x){
    22     sm[x]=sm[c[x][0]]+sm[c[x][1]]+v[x];
    23     sz[x]=sz[c[x][0]]+sz[c[x][1]]+1;
    24 }
    25 
    26 void put(int x,int k){ v[x]+=k; sm[x]+=1ll*k*sz[x]; tag[x]+=k; }
    27 
    28 void push(int x){
    29     if (!tag[x]) return;
    30     if (c[x][0]) put(c[x][0],tag[x]);
    31     if (c[x][1]) put(c[x][1],tag[x]);
    32     tag[x]=0;
    33 }
    34 
    35 void pd(int x){ if (f[x]) pd(f[x]); push(x); }
    36 
    37 int build(int l,int r){
    38     int mid=(l+r)>>1,x=mid;
    39     if (l<mid) c[x][0]=build(l,mid-1),f[c[x][0]]=x;
    40     if (mid<r) c[x][1]=build(mid+1,r),f[c[x][1]]=x;
    41     upd(x); return x;
    42 }
    43 
    44 void rot(int &rt,int x){
    45     int y=f[x],z=f[y],w=c[y][1]==x;
    46     if (y==rt) rt=x; else c[z][c[z][1]==y]=x;
    47     f[x]=z; f[y]=x; f[c[x][w^1]]=y; c[y][w]=c[x][w^1];
    48     c[x][w^1]=y; upd(y);
    49 }
    50 
    51 void splay(int &rt,int x){
    52     for (pd(x); x!=rt; rot(rt,x)){
    53         int y=f[x],z=f[y];
    54         if (y!=rt) (c[z][0]==y)^(c[y][0]==x) ? rot(rt,x) : rot(rt,y);
    55     }
    56     upd(x);
    57 }
    58 
    59 int pre(int x){ splay(rt,x); for (x=c[x][0]; c[x][1]; x=c[x][1]); return x; }
    60 int lst(int x){ splay(rt,x); for (x=c[x][1]; c[x][0]; x=c[x][0]); return x; }
    61 
    62 void Ins(int x,int y){
    63     int k=lst(L[x]); splay(rt,L[x]); splay(c[rt][1],k);
    64     c[k][0]=++nd; v[nd]=y; f[nd]=k; R[++n]=nd;
    65     nd++; c[nd-1][0]=nd; v[nd]=y; f[nd]=nd-1; L[n]=nd;
    66     upd(nd); upd(nd-1); upd(k); upd(rt);
    67 }
    68 
    69 void Add(int x,int y){
    70     int l=pre(L[x]),r=lst(R[x]); splay(rt,l); splay(c[rt][1],r);
    71     put(c[r][0],y); upd(r); upd(rt);
    72 }
    73 
    74 void Del(int x){
    75     int l=pre(L[x]),r=lst(R[x]); splay(rt,l); splay(c[rt][1],r);
    76     c[r][0]=f[c[r][0]]=0; upd(r); upd(rt);
    77 }
    78 
    79 ll Que(int x){ int l=pre(L[x]),r=lst(R[x]); splay(rt,l); splay(c[rt][1],r); return sm[c[r][0]]; }
    80 
    81 int main(){
    82     freopen("anudtq.in","r",stdin);
    83     freopen("anudtq.out","w",stdout);
    84     scanf("%d",&n);
    85     rep(i,1,n) scanf("%d",&a[i]);
    86     rep(i,2,n) scanf("%d%d",&x,&y),x++,y++,add(x,y),add(y,x);
    87     tim=1; dfs(1,0); rt=build(1,tim+1); nd=tim+1; scanf("%d",&m);
    88     rep(i,1,m){
    89         scanf("%d%d",&op,&x); x+=ans+1;
    90         if (op==1) scanf("%d",&y),Ins(x,y);
    91         if (op==2) scanf("%d",&y),Add(x,y);
    92         if (op==3) Del(x);
    93         if (op==4) printf("%lld
    ",ans=Que(x)/2);
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    UPC12617 卡片
    mcmf的dijkstra板子(来自PHY学长)
    UPC9630 Mad Veterinarian
    UPC8173【 哈希和哈希表】Three Friends
    UPC9655 Plug It In!
    UPC8428 网格VI
    UPC4248【数论】数字迷阵
    UPC4247【数论】普通递归关系
    SPOJ
    hdu 5992 Finding Hotels (kdTree)
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10992587.html
Copyright © 2011-2022 走看看