1. 程式人生 > >【WC2013】糖果公園

【WC2013】糖果公園

stdin clu truct 分享圖片 mat 分享 val lan cto

UOJ

題解:樹上莫隊轉移。

一開始UV打錯,WA了一發。

技術分享圖片
  1 #include<cmath>
  2 #include<cstdio>
  3 #include<iostream>
  4 #include<vector>
  5 #include<algorithm>
  6 #define pb push_back
  7 using namespace std;
  8 inline char nc() {
  9     static char b[1<<14],*s=b,*t=b;
 10     return
s==t&&(t=(s=b)+fread(b,1,1<<14,stdin),s==t)?-1:*s++; 11 } 12 inline void read(int &x) { 13 char b = nc(); x = 0; 14 for (; !isdigit(b); b = nc()); 15 for (; isdigit(b); b = nc()) x = x * 10 + b - 0; 16 } 17 typedef long long ll; 18 const int N = 100010; 19 int n, m, QQ, val[N], w[N], a[N], ta[N];
20 ll tans, ans[N]; 21 vector < int > g[N]; 22 inline void ae(int u, int v) { 23 g[u].pb(v); g[v].pb(u); 24 } 25 int sz[N], fa[N], dep[N], son[N], top[N]; 26 int I[N], O[N], f[N*2], D, S, bl[N*2]; 27 int U[N], V[N], T, qq, P[N]; 28 void dfs1(int u, int f) { 29 sz[u] = 1; fa[u] = f; dep[u] = dep[f] + 1
; 30 for (int i = 0, v; i < g[u].size(); ++i) if ((v = g[u][i]) != f) { 31 dfs1(v, u); sz[u] += sz[v]; if (sz[son[u]] < sz[v]) son[u] = v; 32 } 33 } 34 void dfs2(int u, int tp) { 35 I[u] = ++D; f[D] = u; 36 top[u] = tp; if (son[u]) dfs2(son[u], tp); 37 for (int i = 0, v; i < g[u].size(); ++i) 38 if (v = g[u][i], v != fa[u] && v != son[u]) dfs2(v, v); 39 O[u] = ++D; f[D] = u; 40 } 41 inline int findLca(int a, int b) { 42 for (; top[a] != top[b]; a = fa[top[a]]) 43 if (dep[top[a]] < dep[top[b]]) swap(a, b); 44 return dep[a] < dep[b] ? a : b; 45 } 46 struct Q { 47 int l, r, e, t, id; 48 inline void init(int u, int v, int i) { 49 id = i; e = findLca(u, v); t = T; 50 if (I[u] > I[v]) swap(u, v); 51 if (u == e) e = 0, l = I[u], r = I[v]; 52 else l = O[u], r = I[v]; 53 if (l > r) swap(l, r); 54 } 55 inline bool operator<(const Q &q) const { 56 if (bl[l] != bl[q.l]) return bl[l] < bl[q.l]; 57 if (r != q.r) return r < q.r; return t < q.t; 58 } 59 } q[N]; 60 int cn[N], cnt[N]; 61 inline void addc(int c) { 62 tans += val[c] * 1ll * w[++cnt[c]]; 63 } 64 inline void delc(int c) { 65 tans -= val[c] * 1ll * w[cnt[c]--]; 66 } 67 inline void addn(int u) { 68 ++cn[u] == 1 ? addc(a[u]) : delc(a[u]); 69 } 70 inline void deln(int u) { 71 --cn[u] == 1 ? addc(a[u]) : delc(a[u]); 72 } 73 inline void edt(int u, int x) { 74 if ((cn[u] += x) == 1) addc(a[u]); else delc(a[u]); 75 } 76 inline void addt(int t) { 77 if (cn[P[t]] == 1) 78 addc(V[t]), delc(U[t]); 79 a[P[t]] = V[t]; 80 } 81 inline void delt(int t) { 82 if (cn[P[t]] == 1) 83 addc(U[t]), delc(V[t]); 84 a[P[t]] = U[t]; 85 } 86 void solve() { 87 for (int i = 1, l = 1, r = 0, t = 0; i <= qq; ++i) { 88 while (t < q[i].t) addt(++t); 89 while (t > q[i].t) delt(t--); 90 while (r < q[i].r) addn(f[++r]); 91 while (r > q[i].r) deln(f[r--]); 92 while (l < q[i].l) deln(f[l++]); 93 while (l > q[i].l) addn(f[--l]); 94 if (q[i].e) addn(q[i].e); 95 ans[q[i].id] = tans; 96 if (q[i].e) deln(q[i].e); 97 } 98 } 99 int main() { 100 read(n), read(m), read(QQ); S = pow(n * 2, 0.5) + 1; 101 for (int i = 1; i <= m; ++i) read(val[i]); 102 for (int i = 1; i <= n; ++i) read(w[i]); 103 for (int i = 1; i <= n * 2; ++i) bl[i] = (i - 1) / S + 1; 104 for (int i = 1, u, v; i < n; ++i) 105 read(u), read(v), ae(u, v); 106 dfs1(1, 0); dfs2(1, 1); 107 for (int i = 1; i <= n; ++i) read(a[i]), ta[i] = a[i]; 108 for (int op, u, v, i = 0; i < QQ; ++i) { 109 read(op); read(u); read(v); 110 if (op) ++qq, q[qq].init(u, v, qq); 111 else { 112 ++T; P[T] = u; U[T] = ta[u]; V[T] = v; ta[u] = v; 113 } 114 } sort(q + 1, q + 1 + qq); solve(); 115 for (int i = 1; i <= qq; ++i) printf("%lld\n", ans[i]); 116 return 0; 117 }
View Code

【WC2013】糖果公園