3052: [wc2013]糖果公园
Time Limit: 200 Sec Memory Limit: 512 MBSubmit: 962 Solved: 464
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
Sample Input
Sample Output
84
131
27
84
131
27
84
HINT
Source
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 1E5 + 10;
const int Siz = 1234;
typedef long long LL;
struct Mo{
int pos,a,b;
Mo(int _pos = 0,int _a = 0,int _b = 0) {pos = _pos; a = _a; b = _b;}
}M[maxn];
struct Qu{
int L,R,t,beL,beR;
Qu(int _L = 0,int _R = 0,int _beL = 0,int _beR = 0,int _t = 0) {
L = _L; R = _R; beL = _beL; beR = _beR; t = _t;
if (beL > beR) swap(L,R),swap(beL,beR);
}
bool operator < (const Qu &b) const {
if (beL < b.beL) return 1;
if (beL > b.beL) return 0;
if (beR < b.beR) return 1;
if (beR > b.beR) return 0;
return t < b.t;
}
}Q[maxn];
int n,m,q,cnt,Root,top,t,s[maxn],co[maxn],fa[maxn][20],
A,B,Lca,num[maxn],c[maxn],depth[maxn],belong[maxn];
LL now,ans[maxn],va[maxn],w[maxn];
bool vis[maxn];
vector <int> v[maxn];
int getint()
{
int ret = 0;
char ch = getchar();
while (ch < '0' || '9' < ch) ch = getchar();
while ('0' <= ch && ch <= '9') ret = ret*10 + ch - '0',ch = getchar();
return ret;
}
void dfs(int x,int from)
{
for (int i = 1; i < 20; i++) fa[x][i] = fa[fa[x][i-1]][i-1];
int k = top;
for (int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if (to == from) continue;
depth[to] = depth[x] + 1;
fa[to][0] = x;
dfs(to,x);
if (top - k >= Siz) {
++cnt;
while (top != k) belong[s[top--]] = cnt;
}
}
s[++top] = x;
}
void XorV(int x)
{
if (vis[x]) {
now -= va[num[x]]*w[co[num[x]]];
vis[x] = 0; --co[num[x]];
}
else {
++co[num[x]]; vis[x] = 1;
now += va[num[x]]*w[co[num[x]]];
}
}
void XorPath(int p,int q)
{
if (depth[p] < depth[q]) swap(p,q);
while (depth[p] > depth[q]) XorV(p),p = fa[p][0];
if (p == q) return;
while (p != q) {
XorV(p); p = fa[p][0];
XorV(q); q = fa[q][0];
}
}
int LCA(int p,int q)
{
if (depth[p] < depth[q]) swap(p,q);
int Log; for (Log = 0; depth[p] - (1<<Log) >= 1; Log++); --Log;
for (int j = Log; j >= 0; j--)
if (depth[p] - (1<<j) >= depth[q])
p = fa[p][j];
if (p == q) return p;
for (int j = Log; j >= 0; j--)
if (fa[p][j] != fa[q][j])
p = fa[p][j],q = fa[q][j];
return fa[p][0];
}
void Movetime(int cur,int target)
{
if (cur < target) {
for (int i = cur + 1; i <= target; i++) {
if (!M[i].pos) continue;
bool flag = 0;
if (vis[M[i].pos]) XorV(M[i].pos),flag = 1;
num[M[i].pos] = M[i].b;
if (flag) XorV(M[i].pos);
}
}
else {
for (int i = cur; i > target; i--) {
if (!M[i].pos) continue;
bool flag = 0;
if (vis[M[i].pos]) XorV(M[i].pos),flag = 1;
num[M[i].pos] = M[i].a;
if (flag) XorV(M[i].pos);
}
}
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
n = getint(); m = getint(); q = getint();
for (int i = 1; i <= m; i++) va[i] = getint();
for (int i = 1; i <= n; i++) w[i] = getint();
for (int i = 1; i < n; i++) {
int x = getint(),y = getint();
v[x].push_back(y);
v[y].push_back(x);
}
for (int i = 1; i <= n; i++) num[i] = c[i] = getint();
Root = n/2; depth[Root] = 1; dfs(Root,0); int tot = 0;
while (top) belong[s[top--]] = cnt;
for (int i = 1; i <= q; i++) {
int typ = getint(),x = getint(),y = getint();
if (typ) Q[++tot] = Qu(x,y,belong[x],belong[y],i);
else M[i] = Mo(x,c[x],y),c[x] = y;
}
sort(Q + 1,Q + tot + 1);
A = B = Lca = Root; t = 0;
for (int i = 1; i <= tot; i++) {
Movetime(t,Q[i].t); t = Q[i].t;
XorPath(A,Q[i].L); A = Q[i].L;
XorPath(B,Q[i].R); B = Q[i].R;
Lca = LCA(A,B); XorV(Lca);
ans[Q[i].t] = now; XorV(Lca);
}
for (int i = 1; i <= q; i++)
if (ans[i])
printf("%lld\n",ans[i]);
return 0;
}