【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 }
原文地址:https://www.cnblogs.com/yangjiyuan/p/5375428.html