BZOJ3786: 星系探索
Posted ONION_CYC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3786: 星系探索相关的知识,希望对你有一定的参考价值。
【代码调试中】
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; const int maxn=400010; struct cyc{int l,r,rnd,sz,fa,delta,gnum,num,gsum,sum;}t[maxn]; struct edge{int v,from;}e[maxn]; int tote=0,first[maxn]; void insert(int u,int v){tote++;e[tote].v=v;e[tote].from=first[u];first[u]=tote;} int n,m,be[maxn],ed[maxn],tot,a[maxn],b[maxn],c[maxn],st[maxn],root; int read(){ char c;int s=0,t=1; while(!isdigit(c=getchar()))if(c==‘-‘)t=-1; do{s=s*10+c-‘0‘;}while(isdigit(c=getchar())); return s*t; } void dfs(int x){ be[x]=++tot;b[tot]=1;c[tot]=a[x]; for(int i=first[x];i;i=e[i].from){ dfs(e[i].v); } ed[x]=++tot;b[tot]=-1;c[tot]=a[x]; } void up(int k){ t[k].sz=1+t[t[k].l].sz+t[t[k].r].sz; t[k].gsum=t[k].gnum+t[t[k].l].gsum+t[t[k].r].gsum; t[k].sum=t[k].num+t[t[k].l].sum+t[t[k].r].sum; t[t[k].l].fa=t[t[k].r].fa=k; } void modify(int k,int x){t[k].num+=t[k].gnum*x;t[k].sum+=t[k].gsum*x;t[k].delta+=x;} void down(int k){ if(t[k].delta){ modify(t[k].l,t[k].delta);modify(t[k].r,t[k].delta); t[k].delta=0; } } void DFS(int k){ DFS(t[k].l);DFS(t[k].r); up(k); } void build(){ int top=0; for(int i=1;i<=tot;i++){ t[i]=(cyc){0,0,rand(),1,0,0,b[i],c[i],b[i],c[i]}; while(top&&t[st[top]].rnd>t[i].rnd){ t[st[top]].r=t[i].l; t[t[i].l].fa=st[top];t[st[top]].fa=i; t[i].l=st[top--]; } t[st[top]].r=i; t[i].fa=st[top]; st[++top]=i; } DFS(0); t[0]=(cyc){0,0,0,0,0,0,0,0,0}; root=st[1]; t[root].fa=0; } int find(int x){ int sum=t[t[x].l].sz+1; while(t[x].fa!=0){ if(t[t[x].fa].r==x)sum+=t[t[t[x].fa].l].sz+1; x=t[x].fa; } return sum; } int merge(int a,int b){ if(!a||!b)return a^b; if(t[a].rnd<t[b].rnd){ down(a); a=merge(t[a].r,b); up(a); return a; } else{ down(b); merge(a,t[b].l); up(b); return b; } } void split(int k,int &l,int &r,int x){ if(!k)return void(l=r=0); down(k); if(x<t[k].sz+1){ r=k; split(t[k].l,l,t[k].l,x); } else{ l=k; split(t[k].r,t[k].r,r,x-t[k].sz-1); } up(k); } int goroot(int x){ int r=find(be[x]),a,b; split(root,a,b,r); r=t[a].sum; root=merge(a,b); return r; } void change(int x,int y){ int a,b,c; split(root,b,c,find(ed[x])); split(b,a,b,find(be[x])-1); t[b].delta+=y; root=merge(a,b); root=merge(root,c); } void move(int x,int y){ int a,b,c; split(root,b,c,find(ed[x])); split(b,a,b,find(be[x]-1)); root=merge(a,c); t[b].fa=be[y]; split(root,a,c,find(be[x])); root=merge(a,b); root=merge(root,c); } char s[10]; int main(){ srand(233); n=read(); for(int i=2;i<=n;i++)insert(read(),i); for(int i=1;i<=n;i++)a[i]=read(); dfs(1);build(); m=read(); for(int i=1;i<=m;i++){ int x,y; scanf("%s%d",s,&x); if(s[0]==‘Q‘){ printf("%d\n",goroot(x)); } if(s[0]==‘C‘){ scanf("%d",&y); move(x,y); } if(s[0]==‘F‘){ scanf("%d",&y); change(x,y); } } return 0; }
以上是关于BZOJ3786: 星系探索的主要内容,如果未能解决你的问题,请参考以下文章