题目链接: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 }