标签:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define N 100001 typedef long long ll; int v[N<<1],en,first[N],next[N<<1]; void AddEdge(int U,int V) { v[++en]=V; next[en]=first[U]; first[U]=en; } int n,m,a[N],b[N]; int eq,ec,blo,sz,siz[N],top[N],fa[N],dep[N],num[N]; void dfs(int U) { for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]) { fa[v[i]]=U; dep[v[i]]=dep[U]+1; if(siz[top[U]]<sz) { ++siz[top[U]]; top[v[i]]=top[U]; } dfs(v[i]); } } void df2(int U) { num[U]=blo; for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]&&top[v[i]]==top[U]) df2(v[i]); } int lca(int U,int V) { while(U!=V) { if(top[U]!=top[V]) { if(dep[top[U]]<dep[top[V]]) swap(U,V); U=fa[top[U]]; } else { if(dep[U]<dep[V]) swap(U,V); U=fa[U]; } } return U; } struct UPT{int x,y,z;}CH[N]; struct ASK{int l,r,p,t;}Q[N]; bool operator < (const ASK &a,const ASK &b) { if(num[a.l]==num[b.l]) { if(num[a.r]==num[b.r]) return a.t<b.t; return num[a.r]<num[b.r]; } return num[a.l]<num[b.l]; } ll anss[N],ans; int Vs[N],Ws[N],q; bool vis[N]; int T[N]; void Update(int x,int op) { if(op==-1) ans-=(ll)Vs[x]*(ll)Ws[T[x]]; T[x]+=op; if(op==1) ans+=(ll)Vs[x]*(ll)Ws[T[x]]; } void Work(int U,int V,int LCA) { while(U!=LCA) { vis[U]^=1; Update(a[U],vis[U]?1:-1); U=fa[U]; } while(V!=LCA) { vis[V]^=1; Update(a[V],vis[V]?1:-1); V=fa[V]; } } int main() { int x,y; bool op; scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=m;++i) scanf("%d",&Vs[i]); for(int i=1;i<=n;++i) scanf("%d",&Ws[i]); for(int i=1;i<n;++i) { scanf("%d%d",&x,&y); AddEdge(x,y); AddEdge(y,x); } for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<=n;++i) { top[i]=i; siz[i]=1; } sz=(int)pow((double)n,2.0/3.0); dfs(1); for(int i=1;i<=n;++i) if(top[i]==i) { ++blo; df2(i); } en=n; memcpy(b,a,sizeof(int)*(n+1)); for(int i=1;i<=q;++i) { scanf("%d",&op); if(!op) { ++ec; ++en; scanf("%d%d",&CH[ec].x,&CH[ec].y); CH[ec].z=b[CH[ec].x]; b[CH[ec].x]=CH[ec].y; } else { ++eq; scanf("%d%d",&Q[eq].l,&Q[eq].r); Q[eq].t=ec; Q[eq].p=eq; } } sort(Q+1,Q+eq+1); for(int i=1;i<=Q[1].t;++i) a[CH[i].x]=CH[i].y; int LCA=lca(Q[1].l,Q[1].r); Work(Q[1].l,Q[1].r,LCA); Update(a[LCA],1); anss[Q[1].p]=ans; Update(a[LCA],-1); for(int i=2;i<=eq;++i) { if(Q[i-1].t<Q[i].t) for(int j=Q[i-1].t+1;j<=Q[i].t;++j) { if(vis[CH[j].x]) { Update(CH[j].y,1); Update(a[CH[j].x],-1); } a[CH[j].x]=CH[j].y; } else for(int j=Q[i-1].t;j>Q[i].t;--j) { if(vis[CH[j].x]) { Update(CH[j].z,1); Update(a[CH[j].x],-1); } a[CH[j].x]=CH[j].z; } Work(Q[i-1].l,Q[i].l,lca(Q[i-1].l,Q[i].l)); Work(Q[i-1].r,Q[i].r,lca(Q[i-1].r,Q[i].r)); LCA=lca(Q[i].l,Q[i].r); Update(a[LCA],1); anss[Q[i].p]=ans; Update(a[LCA],-1); } for(int i=1;i<=eq;++i) printf("%lld\n",anss[i]); return 0; }
【树上莫队】【带修莫队】bzoj3052 [wc2013]糖果公园
标签:
原文地址:http://www.cnblogs.com/autsky-jadek/p/4428745.html