Bzoj--1036(树链剖分,线段树)
2014-10-05 17:12:36
思路:树链剖分+线段树入门题,有两个操作,写的有点长了。注意细节和姿势就好。
1 /************************************************************************* 2 > File Name: 1036.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sun 05 Oct 2014 04:36:43 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <queue> 16 #include <iostream> 17 #include <algorithm> 18 using namespace std; 19 #define lp (p << 1) 20 #define rp (p << 1|1) 21 #define getmid(l,r) (l + (r - l) / 2) 22 #define MP(a,b) make_pair(a,b) 23 typedef long long ll; 24 const int INF = 1 << 30; 25 const int maxn = 30010; 26 27 int N,Q; 28 int val[maxn]; 29 int first[maxn],next[maxn << 1],ver[maxn << 1],ecnt; 30 int dep[maxn],top[maxn],sz[maxn],son[maxn],fa[maxn],w[maxn],aw[maxn],tsz; 31 32 struct node{ 33 int tmax,sum; 34 }t[maxn << 2]; 35 36 void Add_edge(int u,int v){ 37 next[++ecnt] = first[u]; 38 ver[ecnt] = v; 39 first[u] = ecnt; 40 } 41 42 void Dfs(int p,int pre,int d){ 43 sz[p] = 1; 44 fa[p] = pre; 45 son[p] = -1; 46 dep[p] = d; 47 int v,tmp = 0; 48 for(int i = first[p]; i != -1; i = next[i]) if((v = ver[i]) != pre){ 49 Dfs(v,p,d + 1); 50 if(sz[v] > tmp){ 51 tmp = sz[v]; 52 son[p] = v; 53 } 54 sz[p] += sz[v]; 55 } 56 } 57 58 void Dfs_pos(int p,int tp){ 59 w[p] = ++tsz; 60 aw[tsz] = p; 61 top[p] = tp; 62 if(son[p] != -1) Dfs_pos(son[p],tp); 63 for(int i = first[p]; i != -1; i = next[i]){ 64 int v = ver[i]; 65 if(v != son[p] && v != fa[p]) 66 Dfs_pos(v,v); 67 } 68 } 69 70 void Build_tree(int p,int l,int r){ 71 if(l == r){ 72 t[p].sum = t[p].tmax = val[aw[l]]; 73 return; 74 } 75 int mid = getmid(l,r); 76 Build_tree(lp,l,mid); 77 Build_tree(rp,mid + 1,r); 78 t[p].sum = t[lp].sum + t[rp].sum; 79 t[p].tmax = max(t[lp].tmax,t[rp].tmax); 80 } 81 82 void Update_tree(int a,int c,int p,int l,int r){ 83 if(l == r){ 84 t[p].sum = t[p].tmax = c; 85 return; 86 } 87 int mid = getmid(l,r); 88 if(a <= mid) Update_tree(a,c,lp,l,mid); 89 else Update_tree(a,c,rp,mid + 1,r); 90 t[p].sum = t[lp].sum + t[rp].sum; 91 t[p].tmax = max(t[lp].tmax,t[rp].tmax); 92 } 93 94 int Query_max(int a,int b,int p,int l,int r){ 95 if(a <= l && r <= b) 96 return t[p].tmax; 97 int res = -INF,mid = getmid(l,r); 98 if(a <= mid) res = max(res,Query_max(a,b,lp,l,mid)); 99 if(b > mid) res = max(res,Query_max(a,b,rp,mid + 1,r)); 100 return res; 101 } 102 103 int Find_max(int a,int b){ 104 int f1 = top[a],f2 = top[b],ans = -INF; 105 while(f1 != f2){ 106 if(dep[f1] > dep[f2]){ 107 swap(a,b); 108 swap(f1,f2); 109 } 110 ans = max(ans,Query_max(w[f2],w[b],1,1,tsz)); 111 b = fa[f2]; 112 f2 = top[b]; 113 } 114 if(dep[a] > dep[b]) swap(a,b); 115 ans = max(ans,Query_max(w[a],w[b],1,1,tsz)); 116 return ans; 117 } 118 119 int Query_sum(int a,int b,int p,int l,int r){ 120 if(a <= l && r <= b) 121 return t[p].sum; 122 int res = 0,mid = getmid(l,r); 123 if(a <= mid) res += Query_sum(a,b,lp,l,mid); 124 if(b > mid) res += Query_sum(a,b,rp,mid + 1,r); 125 return res; 126 } 127 128 int Find_sum(int a,int b){ 129 int f1 = top[a],f2 = top[b],ans = 0; 130 while(f1 != f2){ 131 if(dep[f1] > dep[f2]){ 132 swap(a,b); 133 swap(f1,f2); 134 } 135 ans += Query_sum(w[f2],w[b],1,1,tsz); 136 b = fa[f2]; 137 f2 = top[b]; 138 } 139 if(dep[a] > dep[b]) swap(a,b); 140 ans += Query_sum(w[a],w[b],1,1,tsz); 141 return ans; 142 } 143 144 inline void Init(){ 145 memset(first,-1,sizeof(first)); 146 ecnt = 0; 147 tsz = 0; 148 } 149 int main(){ 150 char s[10]; 151 int a,b; 152 scanf("%d",&N); 153 Init(); 154 for(int i = 1; i < N; ++i){ 155 scanf("%d%d",&a,&b); 156 Add_edge(a,b); 157 Add_edge(b,a); 158 } 159 for(int i = 1; i <= N; ++i) 160 scanf("%d",val + i); 161 Dfs(1,0,0); 162 Dfs_pos(1,1); 163 Build_tree(1,1,tsz); 164 scanf("%d",&Q); 165 while(Q--){ 166 scanf("%s%d%d",s,&a,&b); 167 if(s[0] == 'Q'){ 168 if(s[1] == 'M') printf("%d\n",Find_max(a,b)); 169 else printf("%d\n",Find_sum(a,b)); 170 } 171 else{ 172 Update_tree(w[a],b,1,1,tsz); 173 } 174 } 175 return 0; 176 }

浙公网安备 33010602011771号