虽然是个树上莫队裸题还是一遍a
但是发现这题不简单,因为洛谷卡常…
在uoj上过了发现洛谷只过了三个点,
然后各种卡常总算过了
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ; i <= y;++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
using namespace std;
typedef long long ll ;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
template<typename T>inline void read(T&x)
{
x = 0;char c;int sign = 1;
do { c = gc(); if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = gc(); }while(isdigit(c));
x *= sign;
}
const int N = 2e5+500;
int n,m,q,d,sz,size[N],top[N],hson[N];
ll v[N],w[N],c[N],ans[N];
int head[N],nxt[N],to[N],tot;
int id[N],lst[N],deep[N],belong[N],f[N];
struct Data { int x,y,t,lst; }que[N],mod[N];
bool vis[N];int num[N];ll sum;
const bool cmp(Data a,Data b)
{
if(belong[a.x] != belong[b.x]) return belong[a.x] < belong[b.x];
if(belong[a.y] != belong[b.y]) return belong[a.y] < belong[b.y];
return a.t < b.t;
}
inline void add(int x,int y)
{
nxt[tot] = head[x];
to[tot] = y;
head[x] = tot++;
}
void dfs(int x)
{
size[x] = 1;
for(register int i = head[x];~i;i=nxt[i])
if(to[i] != f[x])
{
deep[to[i]] = deep[x] + 1;
f[to[i]] = x;
dfs(to[i]);
size[x] += size[to[i]];
if(size[hson[x]] < size[to[i]])
hson[x] = to[i];
}
}
void dfs2(int x,int t)
{
top[x] = t;id[x] = ++ sz;
if(hson[x]) dfs2(hson[x],t);
for(register int i = head[x];~i;i=nxt[i])
if(to[i] != f[x] && to[i] != hson[x])
dfs2(to[i],to[i]);
}
inline int get_lca(int x,int y)
{
while(top[x] != top[y])
{
if(deep[top[x]] < deep[top[y]]) swap(x,y);
x = f[top[x]];
}
if(deep[x] > deep[y]) swap(x,y);
return x;
}
inline void update(int x,int y)
{
while(x != y)
{
if(deep[x] < deep[y]) swap(x,y);
int k = vis[x] ? -1 : 1;
sum += k * w[num[c[x]] + (k > 0)] * v[c[x]];
num[c[x]] += k;
vis[x] ^= 1;
x = f[x];
}
}
int main()
{
memset(head,-1,sizeof head);
memset(ans,-1,sizeof ans);
read(n); read(m); read(q);
rep(i,1,m) read(v[i]);
rep(i,1,n) read(w[i]);
rep(i,2,n)
{
int u,v;
read(u); read(v);
add(u,v); add(v,u);
}
deep[1] = 1;
f[1] = 1;
dfs(1); dfs2(1,1);
int d = max(1,(int)pow(n,2.0/3)),c1 = 0,c2 = 0,t = 0;
rep(i,1,n) belong[i] = id[i] / d;
rep(i,1,n) read(c[i]),lst[i] = c[i];
rep(i,1,q)
{
int x,y,op;
read(op); read(x); read(y);
if(op == 0)
{
mod[++c1].x = x,mod[c1].y = y,mod[c1].t = i;
mod[c1].lst = lst[x]; lst[x] = y;
}
else
{
if(id[x] > id[y]) swap(x,y);
que[++c2].x = x,que[c2].y = y,que[c2].t = i;
}
}
sort(que + 1,que + 1 + c2,cmp);
que[0].x = 1,que[0].y = 1;
rep(i,1,c2)
{
while(t < c1 && mod[t + 1].t <= que[i].t)
{
++t;
if(vis[mod[t].x])
{
sum -= w[num[c[mod[t].x]]] * v[c[mod[t].x]];
--num[c[mod[t].x]]; c[mod[t].x] = mod[t].y;
++num[mod[t].y]; sum += w[num[mod[t].y]] * v[mod[t].y];
}
c[mod[t].x] = mod[t].y;
}
while(t && mod[t].t > que[i].t)
{
if(vis[mod[t].x])
{
sum -= w[num[c[mod[t].x]]] * v[c[mod[t].x]];
--num[c[mod[t].x]]; c[mod[t].x] = mod[t].lst;
++num[mod[t].lst];sum += w[num[mod[t].lst]] * v[mod[t].lst];
}
c[mod[t].x] = mod[t].lst;
--t;
}
update(que[i - 1].x,que[i].x);
update(que[i - 1].y,que[i].y);
int z = get_lca(que[i].x,que[i].y);
ans[que[i].t] = sum + w[num[c[z]]+1] * v[c[z]];
}
rep(i,1,q) if(~ans[i]) printf("%lld\n",ans[i]);
return 0;
}