[bzoj3786] 星系探索

  splay&&树的dfs序。。。这姿势太神了。

  膜了半天题解。http://blog.csdn.net/PoPoQQQ/article/details/41649197

  其实写那么久主要还是因为。。我的splay模版是含有size域的那种。。。在这题就用不了了TAT(或者说加了也没什么用。。)

  改姿势感觉好蛋疼。。

  比较奇怪的是我改成递归建树后只快了不到1s= =。。时限40s我跑了39+s。。

  很好奇别人2K+代码是怎么写的= =

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #define ll long long
  5 using namespace std;
  6 const int maxn=100233;
  7 struct zs{int too,pre;}e[maxn];
  8 int tot,last[maxn];
  9 int l[maxn],r[maxn],tim;
 10 int ch[maxn<<1][2],numl[maxn<<1],numr[maxn<<1],fa[maxn<<1],v[maxn<<1],cnt;
 11 ll sum[maxn<<1],add[maxn<<1];
 12 int st[maxn<<1],top;
 13 int gg[maxn<<1],val[maxn];
 14 int i,j,k,n,m,x,y,rt;
 15 int ra,fh;char rx,id;
 16 inline int read(){
 17     rx=getchar(),ra=0,fh=1;
 18     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
 19     if(rx=='-')fh=-1,rx=getchar();
 20     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
 21 }
 22 inline void _add(int x,int q){
 23     if(gg[x]==1)v[x]+=q;else if(gg[x]==2)v[x]-=q;
 24     sum[x]+=(ll)(numl[x]-numr[x])*q,
 25     add[x]+=q;
 26 }
 27 inline void upd(int x){
 28     int l=ch[x][0],r=ch[x][1];
 29     sum[x]=sum[l]+sum[r]+v[x],
 30     numl[x]=numl[l]+numl[r]+(gg[x]==1),
 31     numr[x]=numr[l]+numr[r]+(gg[x]==2);
 32 }
 33 inline void pushdown(int x){
 34     if(!add[x])return;
 35     if(ch[x][0])_add(ch[x][0],add[x]);
 36     if(ch[x][1])_add(ch[x][1],add[x]);
 37     add[x]=0;
 38 }
 39 inline void rotate(int x){
 40     int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1;
 41     if(f!=rt)ch[gfa][ch[gfa][1]==f]=x;else rt=x;
 42     fa[fa[fa[ch[f][l]=ch[x][r]]=ch[x][r]=f]=x]=gfa,upd(f);
 43 }
 44 inline void splay(int &rt,int x){
 45     int f,gfa;
 46     for(st[top=1]=f=x;fa[f];st[++top]=(f=fa[f]));
 47     while(top)pushdown(st[top--]);
 48     while(x!=rt){
 49         f=fa[x],gfa=fa[f];
 50         if(f!=rt)
 51             rotate((ch[f][1]==x)!=(ch[gfa][1]==f)?x:f);
 52         rotate(x);
 53     }
 54     upd(x);
 55 }
 56 inline int getmn(int x){while(ch[x][0])x=ch[x][0];return x;}
 57 inline int getmx(int x){while(ch[x][1])x=ch[x][1];return x;}
 58 inline int split(int x,int y){
 59     int a,b;
 60     splay(rt,x),a=getmx(ch[x][0]);
 61     splay(rt,y),b=getmn(ch[y][1]);
 62     splay(rt,a),splay(ch[a][1],b);
 63     return ch[b][0];
 64 }
 65 inline void move(int a,int b){
 66     int x,y,z=split(l[a],r[a]);
 67     x=rt,y=ch[x][1],
 68     ch[y][0]=0,upd(y),upd(x);
 69     x=l[b],splay(rt,x),y=getmn(ch[x][1]),
 70     splay(ch[x][1],y),ch[y][0]=z,fa[z]=y,upd(y),upd(x);
 71 }
 72 inline ll query(int a){x=split(l[1],l[a]);return sum[x];}
 73 inline void change(int p,int q){int x=split(l[p],r[p]);_add(x,q);}
 74 inline void insert(int a,int b){e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;}
 75 inline void dfs(int x){
 76     l[x]=++tim;gg[tim]=1,v[tim]=val[x];
 77     for(int i=last[x];i;i=e[i].pre)dfs(e[i].too);
 78     r[x]=++tim;gg[tim]=2,v[tim]=-val[x];
 79 }
 80 inline void build(int a,int b,int pre){
 81     if(a>b)return;
 82     int mid=(a+b)>>1;
 83     if(pre)ch[pre][mid>pre]=mid;
 84     fa[mid]=pre,
 85     build(a,mid-1,mid),build(mid+1,b,mid);
 86     upd(mid);
 87 }
 88 int main(){
 89     tim=1;rt=1;gg[rt]=3;upd(rt);
 90     n=read();
 91     for(i=2;i<=n;i++)insert(read(),i);
 92     for(i=1;i<=n;i++)val[i]=read();
 93     dfs(1);
 94     tim++;gg[tim]=3;
 95     build(1,tim,0);rt=(1+tim)>>1;
 96     for(m=read();m;m--){
 97         for(id=getchar();id<'A'||id>'Z';id=getchar());
 98         x=read();if(id!='Q')y=read();
 99         if(id=='Q')printf("%lld\n",query(x));
100         if(id=='F')change(x,y);
101         if(id=='C')move(x,y);
102     }
103     return 0;
104 }
View Code

 

posted @ 2016-03-24 21:15  czllgzmzl  阅读(285)  评论(0编辑  收藏  举报