已经调了一个上午了,样例都还没过。急了,求助一下各位大佬,帮忙看看。
低级错误请理解。
用的是括号序列处理树上带修莫队。更新的写法参考的是目前第二篇题解。
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int n,m,q;
vector<int> e[N];
int id[N],rid[N],dfn,DFN[N];
int cnt[N],wor[N],val[N],app[N],sum;
int len,cntq,tim;
int dep[N],f[N][20];
int col[N],tmp[N],pos[N],pre[N],nxt[N],ans[N];
struct typ{
int id,t,l,r,lca;
}que[N];
int log2(int x){
return int(log10(x)/log10(2));
}
bool cmp(typ aa,typ bb){
if(int(aa.l/len)==int(bb.l/len)){
if(int(aa.r/len)==int(bb.r/len))return aa.t<bb.t;
return aa.r<bb.r;
}
return aa.l<bb.l;
}
void dfs(int x,int fa){
id[x]=++dfn;
DFN[dfn]=x;
dep[x]=dep[fa]+1;
f[x][0]=fa;
for(int i=1;i<=16;++i)
f[x][i]=f[f[x][i-1]][i-1];
for(int y:e[x]){
if(y==fa)continue;
dfs(y,x);
}
rid[x]=++dfn;
DFN[dfn]=x;
}
int LCA(int x,int y){
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])
x=f[x][log2(dep[x]-dep[y])];
if(x==y)return x;
for(int i=16;i>=0;i--){
int fx=f[x][i],fy=f[y][i];
if(fx!=fy)x=fx,y=fy;
}
return f[x][0];
}
void add(int x){
if(app[x]==1){
sum-=wor[cnt[col[x]]]*val[col[x]];
cnt[col[x]]--;
}
else{
++cnt[col[x]];
sum+=wor[cnt[col[x]]]*val[col[x]];
}
++app[x];
}
void del(int x){
if(app[x]==2){
++cnt[col[x]];
sum+=wor[cnt[col[x]]]*val[col[x]];
}
else{
sum-=wor[cnt[col[x]]]*val[col[x]];
cnt[col[x]]--;
}
app[col[x]]--;
}
void mdf1(int t){
if(app[pos[t]]&1){
del(pos[t]);
col[pos[t]]=nxt[t];
add(pos[t]);
}
else col[pos[t]]=nxt[t];
}
void mdf2(int t){
if(app[pos[t]]&1){
del(pos[t]);
col[pos[t]]=pre[t];
add(pos[t]);
}
else col[pos[t]]=pre[t];
}
int main(){
cin>>n>>m>>q;
len=pow(n,0.666);
for(int i=1;i<=m;++i)scanf("%d",val+i);
for(int i=1;i<=n;++i)scanf("%d",wor+i);
for(int i=1;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,0);
for(int i=1;i<=n;++i)scanf("%d",col+i),tmp[i]=col[i];
for(int i=1;i<=q;++i){
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op){
++cntq;
if(id[l]>id[r])swap(l,r);
int lca=LCA(l,r);
que[cntq].id=cntq,que[cntq].t=tim;
if(l==lca)que[cntq].l=id[l],que[cntq].r=id[r];
else{
que[cntq].l=rid[l],que[cntq].r=id[r];
que[cntq].lca=lca;
}
}
else{
++tim;
pos[tim]=l;
pre[tim]=tmp[l];
tmp[l]=nxt[tim]=r;
}
}
sort(que+1,que+cntq+1,cmp);
int l=1,r=0,t=0;
for(int i=1;i<=cntq;++i){
while(t>que[i].t)mdf2(t--);
while(t<que[i].t)mdf1(++t);
while(l>que[i].l)add(DFN[--l]);
while(r<que[i].r)add(DFN[++r]);
while(l<que[i].l)del(DFN[l++]);
while(r>que[i].r)del(DFN[r--]);
ans[que[i].id]=sum;
if(que[i].lca)
ans[que[i].id]+=wor[cnt[col[que[i].lca]]+1]*val[col[que[i].lca]];
}
for(int i=1;i<=cntq;++i)cout<<ans[i]<<"\n";
}
个人推测问题肯能出现在更新上。