Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1321 Accepted Submission(s): 344
裸的树链剖分的入门题;
我是套的树状数组实现的
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013/8/14 23:14:27 4 File Name :F:\2013ACM练习\专题学习\数链剖分\HDU3966.cpp 5 ************************************************ */ 6 #pragma comment(linker, "/STACK:1024000000,1024000000") 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 const int MAXN = 50010; 21 struct Edge 22 { 23 int to,next; 24 }edge[MAXN*2]; 25 int head[MAXN],tot; 26 int top[MAXN]; 27 int fa[MAXN]; 28 int deep[MAXN]; 29 int num[MAXN]; 30 int p[MAXN]; 31 int fp[MAXN]; 32 int son[MAXN]; 33 int pos; 34 void init() 35 { 36 tot = 0; 37 memset(head,-1,sizeof(head)); 38 pos = 1;//使用树状数组,编号从头1开始 39 memset(son,-1,sizeof(son)); 40 } 41 void addedge(int u,int v) 42 { 43 edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; 44 } 45 void dfs1(int u,int pre,int d) 46 { 47 deep[u] = d; 48 fa[u] = pre; 49 num[u] = 1; 50 for(int i = head[u];i != -1; i = edge[i].next) 51 { 52 int v = edge[i].to; 53 if(v != pre) 54 { 55 dfs1(v,u,d+1); 56 num[u] += num[v]; 57 if(son[u] == -1 || num[v] > num[son[u]]) 58 son[u] = v; 59 } 60 } 61 } 62 void getpos(int u,int sp) 63 { 64 top[u] = sp; 65 p[u] = pos++; 66 fp[p[u]] = u; 67 if(son[u] == -1) return; 68 getpos(son[u],sp); 69 for(int i = head[u];i != -1;i = edge[i].next) 70 { 71 int v = edge[i].to; 72 if( v != son[u] && v != fa[u]) 73 getpos(v,v); 74 } 75 } 76 77 //树状数组 78 int lowbit(int x) 79 { 80 return x&(-x); 81 } 82 int c[MAXN]; 83 int n; 84 int sum(int i) 85 { 86 int s = 0; 87 while(i > 0) 88 { 89 s += c[i]; 90 i -= lowbit(i); 91 } 92 return s; 93 } 94 void add(int i,int val) 95 { 96 while(i <= n) 97 { 98 c[i] += val; 99 i += lowbit(i); 100 } 101 } 102 void Change(int u,int v,int val)//u->v的路径上点的值改变val 103 { 104 int f1 = top[u], f2 = top[v]; 105 int tmp = 0; 106 while(f1 != f2) 107 { 108 if(deep[f1] < deep[f2]) 109 { 110 swap(f1,f2); 111 swap(u,v); 112 } 113 add(p[f1],val); 114 add(p[u]+1,-val); 115 u = fa[f1]; 116 f1 = top[u]; 117 } 118 if(deep[u] > deep[v]) swap(u,v); 119 add(p[u],val); 120 add(p[v]+1,-val); 121 } 122 int a[MAXN]; 123 int main() 124 { 125 //freopen("in.txt","r",stdin); 126 //freopen("out.txt","w",stdout); 127 int M,P; 128 while(scanf("%d%d%d",&n,&M,&P) == 3) 129 { 130 int u,v; 131 int C1,C2,K; 132 char op[10]; 133 init(); 134 for(int i = 1;i <= n;i++) 135 { 136 scanf("%d",&a[i]); 137 } 138 while(M--) 139 { 140 scanf("%d%d",&u,&v); 141 addedge(u,v); 142 addedge(v,u); 143 } 144 dfs1(1,0,0); 145 getpos(1,1); 146 memset(c,0,sizeof(c)); 147 for(int i = 1;i <= n;i++) 148 { 149 add(p[i],a[i]); 150 add(p[i]+1,-a[i]); 151 } 152 while(P--) 153 { 154 scanf("%s",op); 155 if(op[0] == 'Q') 156 { 157 scanf("%d",&u); 158 printf("%d\n",sum(p[u])); 159 } 160 else 161 { 162 scanf("%d%d%d",&C1,&C2,&K); 163 if(op[0] == 'D') 164 K = -K; 165 Change(C1,C2,K); 166 } 167 } 168 } 169 return 0; 170 }