bzoj 3052 [wc2013]糖果公园
2017-12-02 22:53
302 查看
传送门
至于树上集合的XOR等等这些操作可以看dalao的博客
链接
Sol
置技能:莫队,树上莫队,待修改莫队,树上带修改莫队,足够厚的脸皮卡评测至于树上集合的XOR等等这些操作可以看dalao的博客
链接
Code
// by spli #include<cstring> #include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<vector> #define LL long long using namespace std; const int N=100010; int n,m,qnum; int bin[20]; int SZ; int c ; struct node{ int to,nxt; }e[N<<1];int head ,cnt; LL v ,w ; int bel ,tot; struct ques{ int x,y,id,t; bool operator < (const ques &b)const{ if(bel[x]==bel[b.x]) return bel[y]==bel[b.y]?t<b.t:(bel[y]<bel[b.y]); else return bel[x]<bel[b.x]; } }q ;int Q; struct upd{ int x,y; }ch ;int tim; int fa [20],siz ,dep ; int st ,top; int dfn ,xl; LL num ; bool vis ; LL res; LL ans ; inline int read(){ int x=0,fx=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')fx=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*fx; } inline void add(int f,int t){ cnt++; e[cnt]=(node){t,head[f]}; head[f]=cnt; } void dfs(int u){ st[++top]=u; dfn[u]=++xl; for(int j=1;j<=16;++j) if(dep[u]>=bin[j]) fa[u][j]=fa[fa[u][j-1]][j-1]; else break; for(int i=head[u];i!=-1;i=e[i].nxt){ int v=e[i].to; if(v==fa[u][0]) continue; fa[v][0]=u; dep[v]=dep[u]+1; dfs(v); siz[u]+=siz[v]; if(siz[u]>=SZ){ siz[u]=0; tot++; while(st[top]!=u) bel[st[top--]]=tot; } } siz[u]++; } int LCA(int x,int y){ if(dep[y]<dep[x]) swap(x,y); int d=dep[y]-dep[x]; for(int i=0;bin[i]<=d;++i) if(d&bin[i]) y=fa[y][i]; if(x==y) return x; for(int i=log2(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 rever(int x){ int p=c[x]; LL &t=num[p]; if(vis[x]){ res-=w[t]*v[p]; t--; } else{ t++; res+=w[t]*v[p]; } vis[x]^=1; } void solve(int x,int y){ while(x!=y){ //cout<<x<<" "<<y<<endl; if(dep[x]<dep[y]) swap(x,y); rever(x); x=fa[x][0]; } } void update(int pre){ int pos=ch[pre].x; int &vp=c[pos]; int &vn=ch[pre].y; if(vis[pos]){ rever(pos); swap(vp,vn); rever(pos); } else swap(vp,vn); } int main(){ bin[0]=1; for(int i=1;i<=17;++i) bin[i]=bin[i-1]<<1; memset(head,-1,sizeof(head)); scanf("%d%d%d",&n,&m,&qnum); SZ=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(); int x,y; for(int i=1;i<n;++i){ x=read(); y=read(); add(x,y); add(y,x); } for(int i=1;i<=n;++i) c[i]=read(); dfs(1); while(top) bel[st[top--]]=tot; int op; for(int i=1;i<=qnum;++i){ op=read();x=read();y=read(); if(op==0) ch[++tim]=(upd){x,y}; if(op==1){ if(dfn[x]>dfn[y]) swap(x,y); q[++Q]=(ques){x,y,Q,tim}; } } sort(q+1,q+1+Q); int now=0; while(now<q[1].t) update(++now); solve(q[1].x,q[1].y); int lca=LCA(q[1].x,q[1].y); rever(lca); ans[q[1].id]=res; rever(lca); for(int i=2;i<=qnum;++i){ while(now<q[i].t) update(++now); while(now>q[i].t) update(now--); solve(q[i-1].x,q[i].x); solve(q[i-1].y,q[i].y); lca=LCA(q[i].x,q[i].y); rever(lca); ans[q[i].id]=res; rever(lca); } for(int i=1;i<=Q;++i) printf("%lld\n",ans[i]); return 0; } /* 4 3 5 1 9 2 7 6 5 1 2 3 3 1 3 4 1 2 3 2 1 1 2 1 4 2 0 2 1 1 1 2 1 4 2 */
相关文章推荐
- 【BZOJ 3052】 [wc2013]糖果公园
- bzoj 3052: [wc2013]糖果公园 带修改莫队
- BZOJ3052: [wc2013]糖果公园
- BZOJ3052: [wc2013]糖果公园
- uoj#58./bzoj3052 【WC2013】糖果公园 //树上带修改莫队
- [BZOJ3052][wc2013]糖果公园(树上带修改莫队)
- BZOJ 3052: [wc2013]糖果公园 | 树上莫队
- 【BZOJ3052】[wc2013]糖果公园 带修改的树上莫队
- UOJ 58 BZOJ 3052 [wc2013] 糖果公园
- bzoj 3052: [wc2013]糖果公园(带修改的树上莫队)
- [树上带修莫队] BZOJ3052: [WC2013]糖果公园
- BZOJ3052: [wc2013]糖果公园
- 【BZOJ】3052: [wc2013]糖果公园
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
- 【树上莫队】【带修莫队】bzoj3052 [wc2013]糖果公园
- bzoj3052 [wc2013]糖果公园 (树上带修改莫队)
- UOJ#58/BZOJ 3052【WC2013】糖果公园
- [bzoj3052][WC2013]糖果公园
- bzoj 3052: [wc2013]糖果公园
- BZOJ 3052: [wc2013]糖果公园