树上莫队参见spoj_cot2,带修改莫队参见bzoj2120.这道题就是把这俩和在一起了╭(╯^╰)╮。bzoj上时间很宽松。。大家如果没把握还是不要去爆oj了的好。给大家推荐个好地方UOJ,这题的题号是58。可以先在那过了再说。。uoj的评测机好好的说。。顺便我树上莫队也是从建了uoj的vfk那里学来的。。大家可以去搜一下他的博客。我在这里放链接是不是算侵权??不懂。。只能orz神犇。(因为打错变量调了一下午的我,欲哭无泪。辣鸡样例,打错变量都能过。。)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define ll long long
#define N 100005
using namespace std;
int n,m,qq,block,a[N],h[N],num=0,now=0,prev[N];
int fa[N][18],dep[N],stack[N],top=0,dfn_num=0,dfn[N];
int f[N],Log[N],tot=0,block_num=0,belong[N];
ll w[N],ans=0,ANS[N],v[N];
bool vis[N];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline int swap(int &x,int &y){x^=y;y^=x;x^=y;}
struct edge{
int to,next;
}data[N<<1];
struct timeflow{
int pre,to,pos;
}modify[N];
struct query{
int l,r,id,timen;
}q[N];
inline int cmp(query x,query y){
if(belong[x.l]==belong[y.l]){
return dfn[x.r]==dfn[y.r]?x.timen<y.timen:dfn[x.r]<dfn[y.r];
}else return belong[x.l]<belong[y.l];
}
inline int dfs(int x){
dfn[x]=++dfn_num;int size=0;
for(int i=1;i<=Log[dep[x]];++i)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;
if(y==fa[x][0]) continue;
fa[y][0]=x;dep[y]=dep[x]+1;
size+=dfs(y);
if(size>=block){
++block_num;
while(size--) belong[stack[top--]]=block_num;
}
}
stack[++top]=x;
return size+1;
}
inline void change(int x,int y){
if(vis[x]){
ans-=w[f[a[x]]]*v[a[x]];f[a[x]]--;
a[x]=y;
f[a[x]]++;ans+=w[f[a[x]]]*v[a[x]];
}
else a[x]=y;
}
inline int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
int d=dep[x]-dep[y];
for(int i=0;i<=Log[d];++i)
if(d&(1<<i)) x=fa[x][i];
if(x==y) return x;
for(int i=Log[n];i>=0;--i)
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
inline void reverse(int x){
if(vis[x]) ans-=w[f[a[x]]]*v[a[x]],f[a[x]]--;
else f[a[x]]++,ans+=w[f[a[x]]]*v[a[x]];
vis[x]^=1;
}
inline void solve(int x,int y){
while(x!=y){
if(dep[x]>dep[y]) reverse(x),x=fa[x][0];
else reverse(y),y=fa[y][0];
}
}
int main(){
// freopen("a.in","r",stdin);
n=read();m=read();qq=read();block=pow(n,2.0/3)*0.5;
for(int i=1;i<=m;++i) v[i]=read();
for(int i=1;i<=n;++i) w[i]=read();
for(int i=1;i<n;++i){
int x=read(),y=read();
data[++num].to=y;data[num].next=h[x];h[x]=num;
data[++num].to=x;data[num].next=h[y];h[y]=num;
}
for(int i=1;i<=n;++i) prev[i]=a[i]=read();
Log[0]=-1;for(int i=1;i<=n;++i) Log[i]=Log[i>>1]+1;
dep[1]=1;dfs(1);++block_num;
while(top) belong[stack[top--]]=block_num;
while(qq--){
int op=read(),x=read(),y=read();
if(!op){
modify[++now].pre=prev[x];prev[x]=y;
modify[now].to=y;modify[now].pos=x;
}
else{
q[++tot].l=x;q[tot].r=y;q[tot].timen=now;q[tot].id=tot;
if(belong[x]>belong[y]) swap(q[tot].l,q[tot].r);
}
}sort(q+1,q+tot+1,cmp);
for(int i=1;i<=q[1].timen;++i) a[modify[i].pos]=modify[i].to;
solve(q[1].l,q[1].r);int t=lca(q[1].l,q[1].r);
ANS[q[1].id]=ans+v[a[t]]*(w[f[a[t]]+1]);
for(int i=2;i<=tot;++i){
for(int j=q[i-1].timen;j>q[i].timen;--j) change(modify[j].pos,modify[j].pre);
for(int j=q[i-1].timen;j<q[i].timen;++j) change(modify[j+1].pos,modify[j+1].to);
solve(q[i-1].l,q[i].l);solve(q[i-1].r,q[i].r);
int t=lca(q[i].l,q[i].r);ANS[q[i].id]=ans+v[a[t]]*(w[f[a[t]]+1]);
}
for(int i=1;i<=tot;++i) printf("%lld\n",ANS[i]);
return 0;
}