http://www.lydsy.com/JudgeOnline/problem.php?id=3052
題解啊。。。見vfk的。。。。
看了好久纔看懂啊。。。。。。。QwQ。。。
然後調了好久的參。。。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stack>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
////////////////////////////////////////////////
const int N=100010;
int n,m,q;
LL V[N],W[N];
struct edge{int v,next;}e[N*2];
int head[N],k;
LL ans[N];
int col[N],occur[N],vis[N]; // 顏色 出現次數 是否在鏈上
struct query{int x,y,id,tm,pre;}Q[N],M[N];
int Q_cnt,M_cnt,tmp[N],ind;
int blk_sz,blk_cnt,belong[N];
stack<int>s;
int fa[N][17],sz[N],dep[N];
int curx,cury,curt;
LL curans;
////////////////////////////////////////////////
bool cmp(query A,query 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.tm<B.tm;
}
void adde(int u,int v){e[k]=(edge){v,head[u]};head[u]=k++;}
void dfs(int u)
{
s.push(u);
INE(i,u)
{
int v=e[i].v; if(v==fa[u][0]) continue;
fa[v][0]=u; rep(i,1,16) fa[v][i]=fa[fa[v][i-1]][i-1];
dep[v]=dep[u]+1;
dfs(v);
if(sz[u]+sz[v] >= blk_sz)
{
sz[u]=0;
blk_cnt++;
int v=0;
while(u!=s.top())
{
v=s.top(); s.pop();
belong[v]=blk_cnt;
}
}
else sz[u]+=sz[v];
}
sz[u]++;
}
void reverse(int x)
{
//printf("reverse:%d\n",x);
if(vis[x]) curans-=W[occur[col[x]]]*V[col[x]] , occur[col[x]]--;
else occur[col[x]]++ , curans+=W[occur[col[x]]]*V[col[x]];
vis[x]^=1;
}
void move(int x,int y)
{
if(x==y) return;
for(;x^y;x=fa[x][0])
{
if(dep[x] < dep[y]) swap(x,y);
reverse(x);
}
}
void modify(int x,int c)
{
if(vis[x])
{
reverse(x);
col[x]=c;
reverse(x);
}
else col[x]=c;
}
int getlca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
int d=dep[x]-dep[y];
rep(i,0,16) if(d&1<<i) x=fa[x][i];
if(x==y) return x;
per(i,16,0) if(fa[x][i]^fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
////////////////////////////////////////////////
void input()
{
MS(head,-1);
n=read(); m=read(); q=read(); blk_sz=pow(n,0.66)*0.7;
rep(i,1,m) V[i]=read();
rep(i,1,n) W[i]=read();
rep(i,2,n)
{
int u=read(),v=read();
adde(u,v); adde(v,u);
}
rep(i,1,n) col[i]=tmp[i]=read();
dfs(1);
for(;!s.empty();s.pop()) belong[s.top()]=blk_cnt;
rep(i,1,q)
{
int t=read();
if(t)
{
Q_cnt++;
int x=read(),y=read();
if(belong[x]>belong[y]) swap(x,y);
Q[Q_cnt].x=x; Q[Q_cnt].y=y; Q[Q_cnt].id=Q_cnt; Q[Q_cnt].tm=M_cnt;
}
else
{
M_cnt++;
int x=read(),y=read();
M[M_cnt].x=x; M[M_cnt].y=y;
M[M_cnt].pre=tmp[x],tmp[x]=y;
}
}
sort(&Q[1],&Q[Q_cnt+1],cmp);
}
void solve()
{
curx=1; cury=1; curt=0;
rep(i,1,Q_cnt)
{
for(;curt>Q[i].tm;curt--) modify(M[curt].x,M[curt].pre);
for(;curt<Q[i].tm;curt++) modify(M[curt+1].x,M[curt+1].y);
move(curx,Q[i].x); curx=Q[i].x;
move(cury,Q[i].y); cury=Q[i].y;
int lca=getlca(Q[i].x,Q[i].y);
reverse(lca);
ans[Q[i].id]=curans;
//printf("%d\n",Q[i].id);
reverse(lca);
}
rep(i,1,Q_cnt) printf("%lld\n",ans[i]);
}
////////////////////////////////////////////////
int main()
{
freopen("_.in","r",stdin); freopen("_.out","w",stdout);
input(),solve();
return 0;
}