voidDFS(int root, int father){ int bot = top; for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to; if (v == father) continue; DFS (v, root); if (top - bot >= B) { capt[++ bind] = root; while (top > bot) belong[Stack[top --]] = bind; } } Stack[++ top] = root; }
LinkedForwardStar Link[MAXM << 1]; int Head[MAXN]= {0}; int size = 0;
voidInsert(int u, int v){ Link[++ size].to = v; Link[size].next = Head[u];
Head[u] = size; }
int N, M, Q; LL V[MAXN], W[MAXN]; int pcol[MAXN]; int limit;
int belong[MAXN]; int lind = 0; int Stack[MAXN]; int top = 0; voidDFS_bel(int root, int father){ int bot = top; for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to; if (v == father) continue; DFS_bel (v, root); if (top - bot >= limit) { lind ++; while (top > bot) belong[Stack[top --]] = lind; } } Stack[++ top] = root; }
int father[MAXN]= {0}; int deep[MAXN]; int dfn[MAXN]; int value[MAXN << 1], ranking[MAXN << 1]; int dfsord = 0; voidDFS_LCA(int root, int fa){ father[root] = fa; dfn[root] = ++ dfsord; value[dfsord] = deep[root], ranking[dfsord] = root; for (int i = Head[root]; i; i = Link[i].next) { int v = Link[i].to; if (v == fa) continue; deep[v] = deep[root] + 1; DFS_LCA (v, root); value[++ dfsord] = deep[root], ranking[dfsord] = root; } } pair<int, int> ST[MAXN << 1][20]; voidRMQ(){ for (int i = 1; i <= dfsord; i ++) ST[i][0] = make_pair (value[i], ranking[i]); for (int j = 1; j <= 18; j ++) for (int i = 1; i + (1 << j) - 1 <= dfsord; i ++) ST[i][j] = ST[i][j - 1].first < ST[i + (1 << (j - 1))][j - 1].first ? ST[i][j - 1] : ST[i + (1 << (j - 1))][j - 1]; } intLCA(int x, int y){ int L = dfn[x], R = dfn[y]; if (L > R) swap (L, R); int k = log2 (R - L + 1); return ST[L][k].first < ST[R - (1 << k) + 1][k].first ? ST[L][k].second : ST[R - (1 << k) + 1][k].second; }
LL ans = 0;
structQuerySt { int index; int time; int x, y;
QuerySt (int find = 0, int ftime = 0, int fx = 0, int fy = 0) : index (find), time (ftime), x (fx), y (fy) {}
booloperator < (const QuerySt& p) const { if (belong[x] != belong[p.x]) return belong[x] < belong[p.x]; if (belong[y] != belong[p.y]) return belong[y] < belong[p.y]; return time < p.time; } } ; QuerySt Query[MAXQ]; int qind = 0; int modposi[MAXQ], modtime[MAXQ]; int modpre[MAXQ], modval[MAXQ]; int mind = 0, cur = 0; int state[MAXN]= {0}; int donet[MAXN]= {0}; voidreverse(int p){ if (state[p]) ans -= V[pcol[p]] * W[donet[pcol[p]]], donet[pcol[p]] --; state[p] ^= 1; if (state[p]) donet[pcol[p]] ++, ans += V[pcol[p]] * W[donet[pcol[p]]]; } voidmove(int u, int v){ int lca = LCA (u, v); while (u != lca) reverse (u), u = father[u]; while (v != lca) reverse (v), v = father[v]; } voidextime(int p, int type){ bool exist = false; if (state[modposi[p]]) { exist = true; reverse (modposi[p]); } if (type == 1) { modpre[p] = pcol[modposi[p]]; pcol[modposi[p]] = modval[p]; } else { pcol[modposi[p]] = modpre[p]; } if (exist) reverse (modposi[p]); } voidtimemod(int ptime){ while (cur < mind && modtime[cur + 1] <= ptime) extime (++ cur, 1); while (cur > 0 && modtime[cur] > ptime) extime (cur --, 2); } LL answer[MAXQ]= {0}; voidMoqueue(){ int px = 1, py = 1; for (int i = 1; i <= qind; i ++) { int ind = Query[i].index, time = Query[i].time; int x = Query[i].x, y = Query[i].y; timemod (time); move (px, x), px = x; move (py, y), py = y; int lca = LCA (px, py); reverse (lca); answer[ind] = ans; reverse (lca); } }
intgetnum(){ int num = 0; char ch = getchar ();
while (! isdigit (ch)) ch = getchar (); while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar ();
return num; }
intmain(){ N = getnum (), M = getnum (), Q = getnum (); limit = (int) ceil (pow ((double) N, 2.0 / 3.0)); for (int i = 1; i <= M; i ++) V[i] = (LL) getnum (); for (int i = 1; i <= N; i ++) W[i] = (LL) getnum (); for (int i = 1; i < N; i ++) { int u = getnum (), v = getnum (); Insert (u, v), Insert (v, u); } for (int i = 1; i <= N; i ++) pcol[i] = getnum (); DFS_bel (1, 0); while (top > 0) belong[Stack[top --]] = lind; DFS_LCA (1, 0), RMQ (); for (int i = 1; i <= Q; i ++) { int opt = getnum (); if (opt == 0) { int p = getnum (), col = getnum (); modposi[++ mind] = p, modtime[mind] = i, modval[mind] = col; } elseif (opt == 1) { int x = getnum (), y = getnum (); qind ++, Query[qind] = (QuerySt (qind, i, x, y)); } } sort (Query + 1, Query + qind + 1); Moqueue (); for (int i = 1; i <= qind; i ++) printf ("%lld\n", answer[i]);
intmain(){ N = getnum (), M = getnum (), K = getnum (); limit = sqrt (N); for (int i = 1; i <= N; i ++) { a[i] = getnum (); bel[i] = (i - 1) / limit + 1; } for (int i = 1; i <= M; i ++) { query[i].l = getnum (), query[i].r = getnum (); query[i].ind = i, query[i].ans = 0; } for (int i = 0; i < 16384; i ++) if (__builtin_popcount (i) == K) bits.push_back(i); for (int i = 1; i <= N; i ++) { preans[i] = buck[a[i]]; for (int j = 0; j < (int) bits.size(); j ++) buck[a[i] ^ bits[j]] ++; } sort (query + 1, query + M + 1); for (int i = 1, pl = 1, pr = 0; i <= M; i ++) { int l = query[i].l, r = query[i].r; if (pl < l) subs[pr].push_back((T) {pl, l - 1, - i}); while (pl < l) query[i].ans += preans[pl], pl ++; if (pl > l) subs[pr].push_back((T) {l, pl - 1, i}); while (pl > l) query[i].ans -= preans[pl - 1], pl --; if (pr < r) subs[pl - 1].push_back((T) {pr + 1, r, - i}); while (pr < r) query[i].ans += preans[pr + 1], pr ++; if (pr > r) subs[pl - 1].push_back((T) {r + 1, pr, i}); while (pr > r) query[i].ans -= preans[pr], pr --; } memset (buck, 0, sizeof (buck)); for (int i = 1; i <= N; i ++) { for (int j = 0; j < (int) bits.size(); j ++) buck[a[i] ^ bits[j]] ++; for (int j = 0; j < (int) subs[i].size(); j ++) { int l = subs[i][j].l, r = subs[i][j].r, ind = subs[i][j].delt; for (int k = l; k <= r; k ++) { int tmp = buck[a[k]]; if (k <= i && ! K) tmp --; if (ind > 0) query[ind].ans += tmp; else query[- ind].ans -= tmp; } } } for (int i = 2; i <= M; i ++) query[i].ans += query[i - 1].ans; for (int i = 1; i <= M; i ++) answer[query[i].ind] = query[i].ans; for (int i = 1; i <= M; i ++) write (answer[i]), puts ("");