【WC2013】糖果公园

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

 

posted @ 2017-12-28 16:22  p0ny  阅读(142)  评论(0编辑  收藏  举报