传送门:bzoj3052
题解网上很多,具体做法其实本蒟蒻不是非常了解,还需复习
代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int tot,n,m,t,T,blo,blonum,pre[N];
int in[N],dfn,d[N],pos[N],Q[N],num[N],top;
ll w[N],v[N],c[N],ans,res[N];
int head[N],to[N<<2],nxt[N<<2],vis[N],f[N][17],bin[20];
struct query{int x,y,t,id;}asw[N];
struct change{int x,y,t,pre;}cg[N];
inline int read()
{
char ch=getchar();int x=0,f=1;
while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch<='9' && ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*f;
}
inline void lk(int u,int v)
{
to[++tot]=v;nxt[tot]=head[u];head[u]=tot;
to[++tot]=u;nxt[tot]=head[v];head[v]=tot;
}
inline void swa(int &x,int &y){int t=x;x=y;y=t;}
bool cmp(query a,query b)
{
if(pos[a.x]==pos[b.x]){
if(pos[a.y]==pos[b.y]) return a.t<b.t;
else return pos[a.y]<pos[b.y];
}
else return pos[a.x]<pos[b.x];
}
inline int dfs(int x)
{
int i,sz=0;
in[x]=++dfn;
for(i=1;i<=16;i++){
if(bin[i]<=d[x]) f[x][i]=f[f[x][i-1]][i-1];
else break;
}
for(i=head[x];i;i=nxt[i]){
if(to[i]==f[x][0]) continue;
f[to[i]][0]=x;d[to[i]]=d[x]+1;
sz+=dfs(to[i]);
if(sz>=blo){
blonum++;
for(int k=1;k<=sz;k++) pos[Q[top--]]=blonum;
sz=0;
}
}
Q[++top]=x;
return sz+1;
}
inline void reverse(int x)
{
if(vis[x]) {ans-=w[num[c[x]]]*v[c[x]];num[c[x]]--;}
else {num[c[x]]++;ans+=w[num[c[x]]]*v[c[x]];}
vis[x]^=1;
}
inline void change(int x,int y)
{
if(vis[x]){
reverse(x);
c[x]=y;
reverse(x);
}
else c[x]=y;
}
inline void solve(int x,int y)
{
while(x!=y){
if(d[x]>d[y]) reverse(x),x=f[x][0];
else reverse(y),y=f[y][0];
}
}
inline int LCA(int x,int y)
{
int i;
if(d[x]<d[y]) swa(x,y);
int t=d[x]-d[y];
for(i=0;bin[i]<=t;i++){
if(bin[i]&t) x=f[x][i];
}
for(i=16;i>=0;i--)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
if(x==y) return x;
return f[x][0];
}
int main(){
int i,j,u,des;
bin[0]=1;for(i=1;i<20;i++) bin[i]=(bin[i-1]<<1);
n=read();m=read();T=read();
blo=pow(n,2.0/3)*0.5;
for(i=1;i<=m;i++) v[i]=read();
for(i=1;i<=n;i++) w[i]=read();
for(i=1;i<n;i++){u=read();des=read();lk(u,des);}
for(i=1;i<=n;i++) pre[i]=c[i]=read();
dfs(1);
while(top) pos[Q[top--]]=blonum;
int c1=0,c2=0;
for(i=1;i<=T;i++) {
int op=read(),x=read(),y=read();
if(!op) {c1++;cg[c1].x=x,cg[c1].y=y,cg[c1].pre=pre[x];pre[x]=y;}
else{if(in[x]>in[y]) swa(x,y);c2++;asw[c2].x=x,asw[c2].y=y,asw[c2].id=c2;asw[c2].t=c1;}
}
sort(asw+1,asw+c2+1,cmp);
for(i=1;i<=asw[1].t;i++) change(cg[i].x,cg[i].y);
solve(asw[1].x,asw[1].y);
t=LCA(asw[1].x,asw[1].y);
reverse(t);res[asw[1].id]=ans;reverse(t);
for(i=2;i<=c2;i++){
for(j=asw[i-1].t+1;j<=asw[i].t;j++) change(cg[j].x,cg[j].y);
for(j=asw[i-1].t;j>asw[i].t;j--) change(cg[j].x,cg[j].pre);
solve(asw[i-1].x,asw[i].x);
solve(asw[i-1].y,asw[i].y);
t=LCA(asw[i].x,asw[i].y);
reverse(t);res[asw[i].id]=ans;reverse(t);
}
for(i=1;i<=c2;i++) printf("%lld\n",res[i]);
return 0;
}