bzoj 3786: 星系探索 splay

来源:互联网 发布:贵阳大数据是传销吗 编辑:程序博客网 时间:2024/06/05 04:26

        bzoj真是坑爹,本地跑的差不多的程序,指针比数组快到不知道哪里去了。

       然后我就开始了艰辛的卡常数,最终比很多指针快多辣~~~

       由于有子树移动,那么考虑维护括号序列。也就是dfs入栈为'(',出栈为')',然后'('为正的权值。那么子树移动相当于平衡树的分裂和合并。用splay实现。

       PS:求卡常数大神优化代码>.<

AC代码如下(目前最快的):

#include<bits/stdc++.h>#define ll long long#define N 200005using namespace std;int n,tot,tp,rt,a[N],fst[N],pnt[N],nxt[N],fa[N],c[N][2],q[N];struct node{ int sz,sc; ll icr,num,sum; }P[N];int read(){int x=0; char cr=getchar();while (cr<'0' || cr>'9') cr=getchar();while (cr>='0' && cr<='9'){ x=x*10+cr-'0'; cr=getchar(); }return x;}void add(int x,int y){pnt[++tot]=y; nxt[tot]=fst[x]; fst[x]=tot;}void maintain(int x){node &o=P[x],&l=P[c[x][0]],&r=P[c[x][1]];o.sz=l.sz+r.sz+1; o.sc=l.sc+r.sc+((x<=n)?1:-1);o.sum=l.sum+r.sum+o.num;}void mdy(int x,ll y){if (x){node &o=P[x];o.icr+=y; o.num+=(x<=n)?y:-y; o.sum+=o.sc*y;}}void pushdn(int x){ll &t=P[x].icr;if (t){mdy(c[x][0],t); mdy(c[x][1],t); t=0;}}void clr(int x){int i; q[tp=1]=x;for (i=x; i!=rt; i=fa[i]) q[++tp]=fa[i];while (tp) pushdn(q[tp--]);}int getby(int x,int l){int r=l^1;if (c[x][l]){for (x=c[x][l]; c[x][r]; x=c[x][r]); return x;} else{int y;for (y=fa[x]; y && c[y][l]==x; x=y,y=fa[y]); return y;}}void rot(int x,int &rt){int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;if (y!=rt) c[z][c[z][1]==y]=x; else rt=x;fa[x]=z; fa[y]=x; fa[c[x][r]]=y;c[y][l]=c[x][r]; c[x][r]=y;maintain(y); } void splay(int x,int &rt){int i,y,z; clr(x);for (; x!=rt; rot(x,rt)){y=fa[x]; z=fa[y];if (y!=rt) rot((c[z][0]==y ^ c[y][0]==x)?x:y,rt);}maintain(x);}void dfs(int x,int last){int i,y; q[++tp]=x;for (i=fst[x]; i; i=nxt[i]){y=pnt[i];if (y!=last) dfs(y,x);}q[++tp]=x+n;}void build(int &rt,int l,int r,int last){if (l>r){ rt=0; return; }int mid=l+r>>1;rt=q[mid]; fa[rt]=last;build(c[rt][0],l,mid-1,rt); build(c[rt][1],mid+1,r,rt);P[rt].num=(rt<=n)?a[rt]:-a[rt-n];maintain(rt);}int main(){n=read();int i,x,y,l,r;for (i=2; i<=n; i++){x=read(); add(x,i); add(i,x);}for (i=1; i<=n; i++) a[i]=read();q[tp=1]=n<<1|1;dfs(1,0);q[++tp]=n+1<<1;build(rt,1,tp,0);int cas=read(); char cr; ll ans;while (cas--){cr=getchar(); while (cr<'A' || cr>'Z') cr=getchar();if (cr=='Q'){x=read(); clr(x);ans=P[c[x][0]].sum+P[x].num;for (y=fa[x]; x!=rt; x=y,y=fa[y])if (x==c[y][1]) ans+=P[c[y][0]].sum+P[y].num;printf("%lld\n",ans);} else if (cr=='C'){x=read(); y=read();l=getby(x,0); r=getby(x+n,1);splay(l,rt); splay(r,c[l][1]);x=c[r][0]; c[r][0]=0;maintain(r); maintain(l);splay(y,rt); r=getby(y,1); splay(r,c[y][1]);fa[x]=r; c[r][0]=x;maintain(r); maintain(y);} else if (cr=='F'){x=read();            y=getby(x+n,1); x=getby(x,0);            splay(x,rt); splay(y,c[x][1]);            mdy(c[y][0],read());}}return 0;}


by lych

2016.12.6

0 0
原创粉丝点击