zoukankan      html  css  js  c++  java
  • BZOJ2836:[SHOI2012]魔法树(树链剖分)

    Description

    Input

    Output

    Sample Input

    4
    0 1
    1 2
    2 3
    4
    Add 1 3 1
    Query 0
    Query 1
    Query 2

    Sample Output

    3
    3
    2

    Solution

    退役选手打打板子休闲一下QAQ

    居然能1A真是不可思议

    Code

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define N (100000+1000)
      7 using namespace std;
      8 
      9 struct Edge{int to,next;}edge[N<<1];
     10 struct Node{long long val,add;}Segt[N<<2];
     11 
     12 int Depth[N],Father[N],Size[N];
     13 int T_NUM[N],Top[N],Son[N];
     14 int head[N],num_edge;
     15 int x,y,k,n,m,cnt;
     16 char opt[3];
     17 
     18 void add(int u,int v)
     19 {
     20     edge[++num_edge].to=v;
     21     edge[num_edge].next=head[u];
     22     head[u]=num_edge;
     23 }
     24 
     25 void Dfs1(int x)
     26 {
     27     Depth[x]=Depth[Father[x]]+1;
     28     Size[x]=1;
     29     for (int i=head[x]; i; i=edge[i].next)
     30         if (edge[i].to!=Father[x])
     31         {
     32             Father[edge[i].to]=x;
     33             Dfs1(edge[i].to);
     34             Size[x]+=Size[edge[i].to];
     35             if (!Son[x] || Size[edge[i].to]>Son[x])
     36                 Son[x]=edge[i].to;
     37         }
     38 }
     39 
     40 void Dfs2(int x,int top)
     41 {
     42     Top[x]=top;
     43     T_NUM[x]=++cnt;
     44     if (Son[x]) Dfs2(Son[x],top);
     45     for (int i=head[x]; i; i=edge[i].next)
     46         if (edge[i].to!=Father[x] && edge[i].to!=Son[x])
     47             Dfs2(edge[i].to,edge[i].to);
     48 }
     49 
     50 void Pushdown(int now,int l,int r)
     51 {
     52     if (Segt[now].add)
     53     {
     54         Segt[now<<1].add+=Segt[now].add;
     55         Segt[now<<1|1].add+=Segt[now].add;
     56         int mid=(l+r)>>1;
     57         Segt[now<<1].val+=Segt[now].add*(mid-l+1);
     58         Segt[now<<1|1].val+=Segt[now].add*(r-mid);
     59         Segt[now].add=0;
     60     }
     61 }
     62 
     63 void Update(int now,int l,int r,int l1,int r1,int k)
     64 {
     65     if (r<l1 || l>r1) return;
     66     if (l1<=l && r<=r1)
     67     {
     68         Segt[now].val+=(long long)(r-l+1)*k;
     69         Segt[now].add+=k;
     70         return;
     71     }
     72     Pushdown(now,l,r);
     73     int mid=(l+r)>>1;
     74     Update(now<<1,l,mid,l1,r1,k);
     75     Update(now<<1|1,mid+1,r,l1,r1,k);
     76     Segt[now].val=Segt[now<<1].val+Segt[now<<1|1].val;
     77 }
     78 
     79 long long Query(int now,int l,int r,int l1,int r1)
     80 {
     81     if (l1<=l && r<=r1)
     82         return Segt[now].val;
     83     Pushdown(now,l,r);
     84     int mid=(l+r)>>1;
     85     if (r1<=mid) return Query(now<<1,l,mid,l1,r1);
     86     if (l1>=mid+1) return Query(now<<1|1,mid+1,r,l1,r1);
     87     return Query(now<<1,l,mid,l1,r1)+Query(now<<1|1,mid+1,r,l1,r1);
     88 }
     89 
     90 void Change(int x,int y,int k)
     91 {
     92     int fx=Top[x],fy=Top[y];
     93     while (fx!=fy)
     94     {
     95         if (Depth[fx]<Depth[fy])
     96             swap(x,y),swap(fx,fy);
     97         Update(1,1,n,T_NUM[fx],T_NUM[x],k);
     98         x=Father[fx],fx=Top[x];
     99     }
    100     if (Depth[x]<Depth[y]) swap(x,y);
    101     Update(1,1,n,T_NUM[y],T_NUM[x],k);
    102 }
    103 
    104 int main()
    105 {
    106     scanf("%d",&n);
    107     for (int i=1; i<=n-1; ++i)
    108     {
    109         scanf("%d%d",&x,&y);
    110         x++; y++;
    111         add(x,y); add(y,x);
    112     }
    113     Dfs1(1); Dfs2(1,1);
    114     scanf("%d",&m);
    115     for (int i=1; i<=m; ++i)
    116     {
    117         scanf("%s",opt);
    118         if (opt[0]=='A')
    119         {
    120             scanf("%d%d%d",&x,&y,&k); x++; y++;
    121             Change(x,y,k);
    122         }
    123         else
    124         {
    125             scanf("%d",&x); x++;
    126             printf("%lld
    ",Query(1,1,n,T_NUM[x],T_NUM[x]+Size[x]-1));
    127         }
    128     }
    129 }
  • 相关阅读:
    $ [Contest #4]$求和 思博题
    洛谷$P1864 [NOI2009]$二叉查找树 区间$dp$
    洛谷$P4045 [JSOI2009]$密码 $dp$+$AC$自动机
    $bzoj2560$ 串珠子 容斥+$dp$
    洛谷$P1600$ 天天爱跑步 树上差分
    $loj526 [LibreOJ eta Round #4]$ 子集 图论
    $CF888G Xor-MST$ 最小生成树
    $bzoj4152 The Captain$ 最短路
    洛谷$P3645 [APIO2015]$雅加达的摩天楼 最短路
    $bzoj4722$ 由乃 搜索
  • 原文地址:https://www.cnblogs.com/refun/p/9095172.html
Copyright © 2011-2022 走看看