zoukankan      html  css  js  c++  java
  • 【hdu3966】Aragorn's Story

    题意:给一棵树,并给定各个点权的值,然后有3种操作:
    I C1 C2 K: 把C1与C2的路径上的所有点权值加上K
    D C1 C2 K:把C1与C2的路径上的所有点权值减去K
    Q C:查询节点编号为C的权值 

    裸裸的树剖

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 using namespace std;
      8 
      9 typedef long long LL;
     10 
     11 #define N 50010
     12 
     13 struct Node
     14 {
     15     int to,next;
     16 }e[N<<1];
     17 
     18 int id,cnt;
     19 int head[N];
     20 int num[N],siz[N],top[N],son[N];
     21 int dep[N],pos[N],rank1[N],fa[N];
     22 
     23 LL sum[N<<2],add[N<<2];
     24 
     25 char s[5];
     26 
     27 int n,m,q;
     28 int u,v;
     29 int al,ar,ask;
     30 
     31 inline void init()
     32 {
     33     memset(son,-1,sizeof(son));
     34     memset(head,-1,sizeof(head));
     35 id=0;
     36 cnt=0;
     37 }
     38 
     39 void link(int x,int y)
     40 {
     41     e[++cnt]=(Node){y,head[x]};
     42     head[x]=cnt;
     43 }
     44  
     45 void dfs(int x,int father,int d)
     46 {
     47     siz[x]=1;
     48     dep[x]=d;
     49     fa[x]=father;
     50     for (int i=head[x];~i;i=e[i].next)
     51     {
     52         int t=e[i].to;
     53         if (t!=fa[x])
     54         {
     55             dfs(t,x,d+1);
     56             siz[x]+=siz[t];
     57             if (son[x]==-1 || siz[x]>siz[son[x]])
     58                 son[x]=t;
     59         }
     60     }
     61 }
     62  
     63 void dfs2(int x,int cha)
     64 {
     65     top[x]=cha;
     66     pos[x]=++id;
     67     rank1[pos[x]]=x;
     68     if (son[x]==-1)
     69         return ;    
     70     dfs2(son[x],cha);
     71     for(int i=head[x];~i;i=e[i].next)
     72     {
     73         int t=e[i].to;
     74         if(t!=son[x] && t!=fa[x])
     75             dfs2(t,t);
     76     }
     77 }
     78 
     79 void pushup(int now)
     80 {
     81     sum[now]=max(sum[now<<1],sum[now<<1|1]);
     82 }
     83  
     84 void pushdown(int now,int m)
     85 {
     86     if (add[now])
     87     {
     88         add[now<<1]+=add[now];
     89         add[now<<1|1]+=add[now];
     90         sum[now<<1]+=add[now]*(m-(m>>1));
     91         sum[now<<1|1]+=add[now]*(m>>1);
     92         add[now]=0;
     93     }
     94 }
     95 
     96 void build(int nowl,int nowr,int now)
     97 {
     98     add[now]=0;
     99     if (nowl==nowr)
    100     {
    101         sum[now]=num[rank1[nowl]];
    102         return ;
    103     }
    104     int mid=(nowl+nowr)>>1;
    105     build(nowl,mid,now<<1);
    106     build(mid+1,nowr,now<<1|1);
    107     pushup(now);
    108 }
    109 
    110 void update(int nowl,int nowr,int now,int L,int R,int d)
    111 {
    112     if (nowl>=L && nowr<=R)
    113     {
    114         add[now]+=d;
    115         sum[now]+=d*(nowr-nowl+1);
    116         return ;
    117     }
    118     pushdown(now,nowr-nowl+1);
    119     int mid=nowl+nowr>>1;
    120     if (L<=mid) update(nowl,mid,now<<1,L,R,d);
    121     if (mid<R) update(mid+1,nowr,now<<1|1,L,R,d);
    122     pushup(now);
    123 }
    124 
    125 int query(int nowl,int nowr,int now,int d)
    126 {
    127     int res(0);
    128     if (nowl==nowr)
    129         return sum[now];
    130     pushdown(now,nowr-nowl+1);
    131     int mid=nowl+nowr>>1;
    132     if (d<=mid) res=query(nowl,mid,now<<1,d);
    133     else res=query(mid+1,nowr,now<<1|1,d);
    134     pushup(now);
    135     return res;
    136 }
    137 
    138 void work(int x,int y,int val)
    139 {
    140     while (top[x]!=top[y])
    141     {
    142         if (dep[top[x]]<dep[top[y]])
    143             swap(x,y);
    144         update(1,n,1,pos[top[x]],pos[x],val);
    145         x=fa[top[x]];
    146     }
    147     if (dep[x]>dep[y])
    148         swap(x,y);
    149     update(1,n,1,pos[x],pos[y],val);
    150 }
    151 int main()
    152 {
    153     while (scanf("%d%d%d",&n,&m,&q)!=EOF && n+m+q)
    154     {
    155         init();
    156         for (int i=1;i<=n;i++)
    157             scanf("%d",&num[i]);
    158         for (int i=1;i<=m;i++)
    159         {
    160             scanf("%d%d",&u,&v);
    161             link(u,v);
    162             link(v,u);
    163         }
    164         dfs(1,0,0);
    165         dfs2(1,1);
    166         build(1,n,1);
    167         while (q--)
    168         {
    169             scanf("%s",s);
    170             if (s[0]=='I')
    171             {
    172                 scanf("%d%d%d",&al,&ar,&ask);
    173                 work(al,ar,ask);
    174             }
    175             else if (s[0]=='D')
    176             {
    177                 scanf("%d%d%d",&al,&ar,&ask);
    178                 work(al,ar,-ask);
    179             }
    180             else
    181             {
    182                 scanf("%d",&ask);
    183                 printf("%d
    ",query(1,n,1,pos[ask]));
    184             }
    185         }
    186     }
    187     return 0;
    188 }
  • 相关阅读:
    selenium+allure测试报告添加测试截图
    selenium pytest_html测试报告添加测试步骤截图
    pytest单元测试框架fixture应用
    unittest单元测试框架教程7-unittest.TestSuite类详解
    unittest单元测试框架教程6-unittest.TestCase类详解
    unittest单元测试框架教程5-使用subTest进行循环测试
    unittest单元测试框架教程3-利用unittest测试原理组织测试套件和用例
    unittest单元测试框架教程2-通过TestLoader运行用例
    Python学习相关链接
    GO语言相关的链接整理
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5375428.html
Copyright © 2011-2022 走看看