hdu 3966 Aragorn's Story 树链剖分

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966

Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps out of his kingdom and M edges connect them. It is guaranteed that for any two camps, there is one and only one path connect them. At first Aragorn know the number of enemies in every camp. But the enemy is cunning , they will increase or decrease the number of soldiers in camps. Every time the enemy change the number of soldiers, they will set two camps C1 and C2. Then, for C1, C2 and all camps on the path from C1 to C2, they will increase or decrease K soldiers to these camps. Now Aragorn wants to know the number of soldiers in some particular camps real-time. 
 
题意描述:给定一棵树和节点上的值,然后执行下面操作:
I u,v,value:把u和v路径上的节点的值都加上value;
D u,v,value:把u和v路径上的节点的值都减去value;
Q u:询问节点u上的值。
 
算法分析:最近学习树链剖分,就把这道题作为入门题练习。这里有树链剖分的基础
这道题很容易爆栈,所以得手动扩栈。
  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<cmath>
  7 #include<algorithm>
  8 #include<queue>
  9 #include<vector>
 10 #define inf 0x7fffffff
 11 #define lson l,m,rt<<1
 12 #define rson m+1,r,rt<<1|1
 13 using namespace std;
 14 typedef long long LL;
 15 const int maxn=50000+10;
 16 
 17 int n,m,q;
 18 int siz[maxn],son[maxn],val[maxn],dep[maxn];
 19 int tid[maxn],tid2[maxn],tot;
 20 int fa[maxn],top[maxn];
 21 vector<int> G[maxn];
 22 
 23 void dfs1(int u,int father,int d)
 24 {
 25     dep[u]=d;
 26     fa[u]=father;
 27     siz[u]=1;
 28     for (int i=0 ;i<G[u].size() ;i++)
 29     {
 30         int v=G[u][i];
 31         if(v!=father)
 32         {
 33             dfs1(v,u,d+1);
 34             siz[u]+=siz[v];
 35             if(son[u]==-1||siz[v]>siz[son[u]])
 36                 son[u]=v;
 37         }
 38     }
 39 }
 40 
 41 void dfs2(int u,int tp)
 42 {
 43     top[u]=tp;
 44     tid[u]= ++tot;
 45     tid2[tid[u]]=u;
 46     if (son[u]==-1) return;
 47     dfs2(son[u],tp);
 48     for (int i=0 ;i<G[u].size() ;i++)
 49     {
 50         int v=G[u][i];
 51         if(v!=son[u]&&v!=fa[u])
 52             dfs2(v,v);
 53     }
 54 }
 55 
 56 int sum[maxn<<2],col[maxn<<2];
 57 void PushUP(int rt)
 58 {
 59     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
 60 }
 61 
 62 void PushDown(int rt,int len)
 63 {
 64     if (col[rt]!=0)
 65     {
 66         col[rt<<1] += col[rt];
 67         col[rt<<1|1] += col[rt];
 68         sum[rt<<1] += (len-(len>>1))*col[rt];
 69         sum[rt<<1|1] += (len>>1)*col[rt];
 70         col[rt]=0;
 71     }
 72 }
 73 
 74 void build(int l,int r,int rt)
 75 {
 76     col[rt]=0;
 77     if (l==r)
 78     {
 79         sum[rt]=val[tid2[l] ];
 80         return ;
 81     }
 82     int mid=(l+r)>>1;
 83     build(l,mid,rt<<1);
 84     build(mid+1,r,rt<<1|1);
 85     PushUP(rt);
 86 }
 87 
 88 void update(int L,int R,int value,int l,int r,int rt)
 89 {
 90     if (L<=l && r<=R)
 91     {
 92         sum[rt] += (r-l+1)*value;
 93         col[rt] += value;
 94         return ;
 95     }
 96     PushDown(rt,(r-l+1));
 97     int mid=(l+r)>>1;
 98     if (L<=mid) update(L,R,value,l,mid,rt<<1);
 99     if (R>mid) update(L,R,value,mid+1,r,rt<<1|1);
100     PushUP(rt);
101 }
102 
103 int query(int l,int r,int rt,int u)
104 {
105     if (l==r) return sum[rt];
106     PushDown(rt,r-l+1);
107     int mid=(l+r)>>1;
108     int ans;
109     if (u<=mid) ans=query(l,mid,rt<<1,u);
110     else ans=query(mid+1,r,rt<<1|1,u);
111     PushUP(rt);
112     return ans;
113 }
114 
115 void solve(int u,int v,int value)
116 {
117     int f1=top[u],f2=top[v];
118     while (f1 != f2)
119     {
120         if (dep[f1]<dep[f2]) {swap(f1,f2);swap(u,v); }
121         update(tid[f1],tid[u],value,1,n,1);
122         u=fa[f1] ;f1=top[u] ;
123     }
124     if (dep[u]<dep[v]) swap(u,v);
125     update(tid[v],tid[u],value,1,n,1);
126 }
127 
128 int main()
129 {
130     while (scanf("%d%d%d",&n,&m,&q)!=EOF)
131     {
132         memset(sum,0,sizeof(sum));
133         memset(col,0,sizeof(col));
134         memset(son,-1,sizeof(son));
135         tot=0;
136         for (int i=1 ;i<=n ;i++) scanf("%d",&val[i]);
137         int u,v,value;
138         char str[3];
139         for (int i=1 ;i<=n ;i++) G[i].clear();
140         for (int i=1 ;i<=m ;i++)
141         {
142             scanf("%d%d",&u,&v);
143             G[u].push_back(v);
144             G[v].push_back(u);
145         }
146         dfs1(1,0,0);
147         dfs2(1,1);
148         build(1,n,1);
149         while (q--)
150         {
151             scanf("%s",str);
152             if (str[0]=='Q')
153             {
154                 scanf("%d",&u);
155                 printf("%d
",query(1,n,1,tid[u]));
156             }
157             else
158             {
159                 scanf("%d%d%d",&u,&v,&value);
160                 if (str[0]=='D') value=-value;
161                 solve(u,v,value);
162             }
163         }
164     }
165     return 0;
166 }
 
原文地址:https://www.cnblogs.com/huangxf/p/4342486.html