【bzoj 3786】星系探索

Description

物理学家小C的研究正遇到某个瓶颈。

他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球。主星球没有依赖星球。

我们定义依赖关系如下:若星球a的依赖星球是b,则有星球a依赖星球b。此外,依赖关系具有传递性,即若星球a依赖星球b,星球b依赖星球c,则有星球a依赖星球c。

对于这个神秘的星系中,小C初步探究了它的性质,发现星球之间的依赖关系是无环的。并且从星球a出发只能直接到达它的依赖星球b。

每个星球i都有一个能量系数wi。小C想进行若干次实验,第i次实验,他将从飞船上向星球di发射一个初始能量为0的能量收集器,能量收集器会从星球di开始前往主星球,并收集沿途每个星球的部分能量,收集能量的多少等于这个星球的能量系数。

但是星系的构成并不是一成不变的,某些时刻,星系可能由于某些复杂的原因发生变化。

有些时刻,某个星球能量激发,将使得所有依赖于它的星球以及他自己的能量系数均增加一个定值。还有可能在某些时刻,某个星球的依赖星球会发生变化,但变化后依然满足依赖关系是无环的。

现在小C已经测定了时刻0时每个星球的能量系数,以及每个星球(除了主星球之外)的依赖星球。接下来的m个时刻,每个时刻都会发生一些事件。其中小C可能会进行若干次实验,对于他的每一次实验,请你告诉他这一次实验能量收集器的最终能量是多少。

Input

第一行一个整数n,表示星系的星球数。

接下来n-1行每行一个整数,分别表示星球2-n的依赖星球编号。

接下来一行n个整数,表示每个星球在时刻0时的初始能量系数wi。

接下来一行一个整数m,表示事件的总数。

事件分为以下三种类型。

(1)"Q di"表示小C要开始一次实验,收集器的初始位置在星球di。

(2)"C xi yi"表示星球xi的依赖星球变为了星球yi。

(3)"F pi qi"表示星球pi能量激发,常数为qi。

Output

对于每一个事件类型为Q的事件,输出一行一个整数,表示此次实验的收集器最终能量。

Sample Input

3
1
1
4 5 7
5
Q 2
F 1 3
Q 2
C 2 3
Q 2

Sample Output

9
15
25

HINT

n<=100000,m<=300000,1<di,xi<=n,wi,qi<=100000.保证操作合法。注意w_i>=0。

 

纪念一下一道调了两天发现自己忘开long long的题>_<

简单地写一下题解吧。

首先,为了将子树变成一段连续的区间,我们需要将每个点拆成两个,一个代表入栈,一个代表出栈。入栈时点权为正,出栈时为负,这样一个点到根节点的路径上的点权和等于前缀和。先在整棵树上dfs,把这些点塞进一个队列里,根据队列把树建好,然后就是疯狂地拆拆拆和splay。

 

fhq-treap分裂过程中记录父亲【Time:32912ms】(因为多了一个find函数还需要记一下父亲)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #define LL long long
  6 using namespace std;
  7 const int N=2e5+10;
  8 int n,m,cnt,tmp,x,y,root,rt1,rt2,rt3;
  9 int st[N],q[N],first[N],ch[N][7];
 10 LL sh[N][3];
 11 char op[2];
 12 struct edge{int to,next;}e[N];
 13 #define lc ch][0
 14 #define rc ch][1
 15 #define rnd ch][2
 16 #define sz ch][3
 17 #define xi ch][4
 18 #define num ch][5
 19 #define fa ch][6
 20 #define v sh][0
 21 #define sum sh][1
 22 #define tag sh][2
 23 int read()
 24 {
 25     int x=0,f=1;char c=getchar();
 26     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 27     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
 28     return x*f;
 29 }
 30 void ins(int from,int to){e[++cnt]=(edge){to,first[from]};first[from]=cnt;}
 31 void dfs(int x)
 32 {
 33     q[++cnt]=x;
 34     for(int i=first[x];i;i=e[i].next)dfs(e[i].to);
 35     q[++cnt]=x+n;
 36 }
 37 void up(int w)
 38 {
 39     int l=w[lc],r=w[rc];
 40     w[sz]=l[sz]+r[sz]+1;
 41     w[num]=l[num]+r[num]+w[xi];
 42     w[sum]=l[sum]+r[sum]+w[v];
 43 }
 44 void dn(int w)
 45 {
 46     int l=w[lc],r=w[rc];LL t=w[tag];
 47     if(!t)return;w[tag]=0;
 48     if(l)l[tag]+=t,l[v]+=t*l[xi],l[sum]+=t*l[num];
 49     if(r)r[tag]+=t,r[v]+=t*r[xi],r[sum]+=t*r[num];
 50 //    printf("l:%d xi:%d r:%d xi:%d\n",l,l[xi],r,r[xi]);
 51 }
 52 void check(int w){if(!w)return;check(w[lc]);check(w[rc]);up(w);}
 53 int build(int n)
 54 {
 55     int top=0,w;
 56     for(int i=1;i<=n;i++)
 57     {
 58         w=q[i];w[rnd]=rand();
 59         while(top&&st[top][rnd]>w[rnd])
 60         {
 61             w[lc][fa]=st[top];st[top][rc]=w[lc];
 62             st[top][fa]=w;w[lc]=st[top--];
 63         }
 64         w[fa]=st[top];st[top][rc]=w;st[++top]=w;
 65     }
 66     ch[0][1]=0;st[1][fa]=0;check(st[1]);
 67     return st[1];
 68 }
 69 void split(int w,int& l,int fal,int& r,int far,int k)
 70 {
 71     if(!w){l=r=0;return;}
 72     dn(w);int lson=w[lc][sz];
 73     if(k<=lson)w[fa]=far,r=w,split(w[lc],l,fal,w[lc],w,k);
 74     else w[fa]=fal,l=w,split(w[rc],w[rc],w,r,far,k-lson-1);
 75     up(w);
 76 }
 77 int merge(int a,int b)
 78 {
 79     if(!a||!b)return a+b;
 80     if(a[rnd]<b[rnd]){dn(a);a[rc]=merge(a[rc],b);a[rc][fa]=a;up(a);return a;}
 81     else {dn(b);b[lc]=merge(a,b[lc]);b[lc][fa]=b;up(b);return b;}
 82 }
 83 int find(int x)
 84 {
 85     int ans=x[lc][sz]+1;
 86     while(x[fa])
 87     {
 88         if(x[fa][rc]==x)ans+=x[fa][lc][sz]+1;
 89         x=x[fa];
 90     }
 91     return ans;
 92 }
 93 void query()
 94 {
 95     x=read();rt1=rt2=0;split(root,rt1,0,rt2,0,find(x));
 96     printf("%lld\n",rt1[sum]);root=merge(rt1,rt2);
 97 }
 98 void change()
 99 {
100     x=read();y=read();rt1=rt2=rt3=0;
101     split(root,rt1,0,rt3,0,find(x+n));
102     root=rt1;rt1=0;split(root,rt1,0,rt2,0,find(x)-1);
103     root=merge(rt1,rt3);rt1=rt3=0;
104     split(root,rt1,0,rt3,0,find(y));
105     root=merge(rt1,rt2);root=merge(root,rt3);
106 }
107 void add()
108 {
109     x=read();y=read();rt1=rt2=rt3=0;
110     split(root,rt1,0,rt3,0,find(x+n));
111     root=rt1;rt1=0;split(root,rt1,0,rt2,0,find(x)-1);
112     int w=rt2;w[tag]+=y;w[v]+=y*w[xi];w[sum]+=1ll*y*w[num];
113     root=merge(rt1,rt2);root=merge(root,rt3);
114 }
115 void print(int w,int dir)
116 {
117     if(!w)return;
118     if(dir==0)printf("from-left ");
119     if(dir==1)printf("from-right ");
120     printf("[%d] fa:%d v:%lld sum:%lld lson:%d rson:%d\n",w,w[fa],w[v],w[sum],w[lc],w[rc]);
121     print(w[lc],0);print(w[rc],1);
122 }
123 int main()
124 {
125     n=read();
126     for(int i=2;i<=n;i++)tmp=read(),ins(tmp,i);
127     for(int i=1;i<=n;i++)tmp=read(),i[v]=tmp,(i+n)[v]=-tmp,i[xi]=1,(i+n)[xi]=-1;
128     cnt=0;dfs(1);root=build(n*2);m=read();//print(root,-1);
129     while(m--)
130     {
131         scanf("%s",op+1);
132         if(op[1]=='Q')query();
133         else if(op[1]=='C')change();
134         else add();
135 //        print(root,-1);
136     }
137     return 0;
138 }
View Code

 

fhq-treap up时更新父亲【Time:37452ms】(分裂出来的根节点的父亲记得清零)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #define LL long long
  6 using namespace std;
  7 const int N=2e5+10;
  8 int n,m,cnt,tmp,x,y,root,rt1,rt2,rt3;
  9 int st[N],q[N],first[N],ch[N][7];
 10 LL sh[N][3];
 11 char op[2];
 12 struct edge{int to,next;}e[N];
 13 #define lc ch][0
 14 #define rc ch][1
 15 #define rnd ch][2
 16 #define sz ch][3
 17 #define xi ch][4
 18 #define num ch][5
 19 #define fa ch][6
 20 #define v sh][0
 21 #define sum sh][1
 22 #define tag sh][2
 23 int read()
 24 {
 25     int x=0,f=1;char c=getchar();
 26     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 27     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
 28     return x*f;
 29 }
 30 void ins(int from,int to){e[++cnt]=(edge){to,first[from]};first[from]=cnt;}
 31 void dfs(int x)
 32 {
 33     q[++cnt]=x;
 34     for(int i=first[x];i;i=e[i].next)dfs(e[i].to);
 35     q[++cnt]=x+n;
 36 }
 37 void up(int w)
 38 {
 39     int l=w[lc],r=w[rc];
 40     w[sz]=l[sz]+r[sz]+1;
 41     w[num]=l[num]+r[num]+w[xi];
 42     w[sum]=l[sum]+r[sum]+w[v];
 43     if(l)l[fa]=w;if(r)r[fa]=w;
 44 }
 45 void dn(int w)
 46 {
 47     int l=w[lc],r=w[rc];LL t=w[tag];
 48     if(!t)return;w[tag]=0;
 49     if(l)l[tag]+=t,l[v]+=t*l[xi],l[sum]+=t*l[num];
 50     if(r)r[tag]+=t,r[v]+=t*r[xi],r[sum]+=t*r[num];
 51 }
 52 void check(int w){if(!w)return;check(w[lc]);check(w[rc]);up(w);}
 53 int build(int n)
 54 {
 55     int top=0,w;
 56     for(int i=1;i<=n;i++)
 57     {
 58         w=q[i];w[rnd]=rand();
 59         while(top&&st[top][rnd]>w[rnd])st[top][rc]=w[lc],w[lc]=st[top--];
 60         st[top][rc]=w;st[++top]=w;
 61     }
 62     ch[0][1]=0;st[1][fa]=0;check(st[1]);
 63     return st[1];
 64 }
 65 void split(int w,int& l,int fal,int& r,int far,int k)
 66 {
 67     if(!w){l=r=0;return;}
 68     dn(w);int lson=w[lc][sz];
 69     if(k<=lson)r=w,split(w[lc],l,fal,w[lc],w,k);
 70     else l=w,split(w[rc],w[rc],w,r,far,k-lson-1);
 71     up(w);
 72 }
 73 int merge(int a,int b)
 74 {
 75     if(!a||!b)return a+b;
 76     if(a[rnd]<b[rnd]){dn(a);a[rc]=merge(a[rc],b);up(a);return a;}
 77     else {dn(b);b[lc]=merge(a,b[lc]);up(b);return b;}
 78 }
 79 int find(int x)
 80 {
 81     int ans=x[lc][sz]+1;
 82     while(x[fa])
 83     {
 84         if(x[fa][rc]==x)ans+=x[fa][lc][sz]+1;
 85         x=x[fa];
 86     }
 87     return ans;
 88 }
 89 void query()
 90 {
 91     x=read();rt1=rt2=0;split(root,rt1,0,rt2,0,find(x));
 92     rt1[fa]=rt2[fa]=0;printf("%lld\n",rt1[sum]);root=merge(rt1,rt2);root[fa]=0;
 93 }
 94 void change()
 95 {
 96     x=read();y=read();rt1=rt2=rt3=0;
 97     split(root,rt1,0,rt3,0,find(x+n));
 98     rt1[fa]=rt3[fa]=0;root=rt1;rt1=0;
 99     split(root,rt1,0,rt2,0,find(x)-1);
100     rt1[fa]=rt2[fa]=0;root=merge(rt1,rt3);rt1=rt3=0;
101     split(root,rt1,0,rt3,0,find(y));
102     root=merge(rt1,rt2);root=merge(root,rt3);root[fa]=0;
103 }
104 void add()
105 {
106     x=read();y=read();rt1=rt2=rt3=0;
107     split(root,rt1,0,rt3,0,find(x+n));
108     rt1[fa]=rt3[fa]=0;root=rt1;rt1=0;
109     split(root,rt1,0,rt2,0,find(x)-1);rt1[fa]=rt2[fa]=0;
110     int w=rt2;w[tag]+=y;w[v]+=y*w[xi];w[sum]+=1ll*y*w[num];
111     root=merge(rt1,rt2);root=merge(root,rt3);root[fa]=0;
112 }
113 int main()
114 {
115     n=read();
116     for(int i=2;i<=n;i++)tmp=read(),ins(tmp,i);
117     for(int i=1;i<=n;i++)tmp=read(),i[v]=tmp,(i+n)[v]=-tmp,i[xi]=1,(i+n)[xi]=-1;
118     cnt=0;dfs(1);
119     root=build(n*2);m=read();
120     while(m--)
121     {
122         scanf("%s",op+1);
123         if(op[1]=='Q')query();
124         else if(op[1]=='C')change();
125         else add();
126     }
127     return 0;
128 }
View Code

 

splay直接查找前驱后继【Time:25484 ms】(数组版仿佛很容易TLE……慎重)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 using namespace std;
  5 const int inf=0x3f3f3f3f;
  6 const int N=100010;
  7 struct node{int ch[2],size,fa,t,num;long long v,sum,tag;}tr[N<<1];
  8 struct edge{int next,to;}e[N];
  9 int n,m,f,root,cnt;
 10 int head[N],q[N<<1],s[N];
 11 int read()
 12 {
 13     int x=0,f=1;char c=getchar();
 14     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 15     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
 16     return x*f;
 17 }
 18 void insert(int a,int b){cnt++;e[cnt].to=b;e[cnt].next=head[a];head[a]=cnt;}
 19 void dfs(int x)
 20 {
 21     q[++cnt]=x+1;
 22     for(int i=head[x];i;i=e[i].next)dfs(e[i].to);
 23     q[++cnt]=x+n+1;
 24 }
 25 void pushup(int x)
 26 {
 27     int l=tr[x].ch[0],r=tr[x].ch[1];
 28     tr[x].size=tr[l].size+tr[r].size+1;
 29     tr[x].num=tr[l].num+tr[r].num+tr[x].t;
 30     tr[x].sum=tr[l].sum+tr[r].sum+tr[x].v;
 31 }
 32 void pushdown(int x)
 33 {
 34     int l=tr[x].ch[0],r=tr[x].ch[1];long long tag=tr[x].tag;
 35     if(l)tr[l].tag+=tag,tr[l].sum+=tag*tr[l].num,tr[l].v+=tag*tr[l].t;
 36     if(r)tr[r].tag+=tag,tr[r].sum+=tag*tr[r].num,tr[r].v+=tag*tr[r].t;
 37     tr[x].tag=0;
 38 }
 39 void rotate(int x,int& k)
 40 {
 41     int y=tr[x].fa,z=tr[y].fa,l,r;
 42     if(tr[y].ch[0]==x)l=0;else l=1;r=l^1;
 43     if(y==k)k=x;
 44     else{if(tr[z].ch[0]==y)tr[z].ch[0]=x;else tr[z].ch[1]=x;}
 45     tr[x].fa=z;tr[y].fa=x;tr[tr[x].ch[r]].fa=y;
 46     tr[y].ch[l]=tr[x].ch[r];tr[x].ch[r]=y;
 47     pushup(y);pushup(x);
 48 }
 49 void splay(int x,int& k)
 50 {
 51     int top=0;s[++top]=x;
 52     for(int i=x;tr[i].fa;i=tr[i].fa)s[++top]=tr[i].fa;
 53     for(int i=top;i;i--)if(tr[s[i]].tag)pushdown(s[i]);
 54     while(x!=k)
 55     {
 56         int y=tr[x].fa,z=tr[y].fa;
 57         if(y!=k)
 58         {
 59             if((tr[y].ch[0]==x)^(tr[z].ch[0]==y))rotate(x,k);
 60             else rotate(y,k);
 61         }
 62         rotate(x,k);
 63     }
 64 }
 65 int fmin(int x){while(tr[x].ch[0])x=tr[x].ch[0];return x;}
 66 int fmax(int x){while(tr[x].ch[1])x=tr[x].ch[1];return x;}
 67 void split(int l,int r)
 68 {
 69     splay(l,root);int x=fmax(tr[l].ch[0]);
 70     splay(r,root);int y=fmin(tr[r].ch[1]);
 71     splay(x,root);splay(y,tr[x].ch[1]);
 72 }
 73 void build(int l,int r,int last)
 74 {
 75     if(l>r)return;
 76     int mid=(l+r)>>1;
 77     tr[q[mid]].fa=q[last];
 78     tr[q[last]].ch[mid>last]=q[mid];
 79     build(l,mid-1,mid);build(mid+1,r,mid);
 80     pushup(q[mid]);
 81 }
 82 void print(int x)
 83 {
 84     printf("[%d] [fa]%d [v]%lld [sum]%lld [t]%d [num]%d\n",x,tr[x].fa,tr[x].v,tr[x].sum,tr[x].t,tr[x].num);
 85     int l=tr[x].ch[0],r=tr[x].ch[1];
 86     if(l)print(l);if(r)print(r);
 87 }
 88 void query()
 89 {
 90     int x=read();
 91     splay(x+1,root);
 92     printf("%lld\n",tr[tr[x+1].ch[0]].sum+tr[x+1].v);
 93 }
 94 void change()
 95 {
 96     int x=read(),y=read();
 97     split(x+1,x+n+1);
 98     int yi=tr[root].ch[1],xi=tr[yi].ch[0];
 99     tr[yi].ch[0]=0;pushup(yi);pushup(root);
100     splay(y+1,root);
101     int u=fmin(tr[y+1].ch[1]);
102     splay(u,tr[y+1].ch[1]);
103     tr[xi].fa=u;
104     tr[u].ch[0]=xi;
105     pushup(u);pushup(root);
106 }
107 void add()
108 {
109     int x=read();long long tag=read();
110     split(x+1,x+n+1);
111     int yi=tr[root].ch[1],xi=tr[yi].ch[0];
112     tr[xi].tag+=tag;tr[xi].sum+=tag*tr[xi].num;tr[xi].v+=tag*tr[xi].t;
113     pushup(yi);pushup(root);
114 }
115 int main()
116 {
117     char str[1];
118     n=read();
119     for(int i=2;i<=n;i++)f=read(),insert(f,i);
120     for(int i=1;i<=n;i++)f=read(),tr[i+1].v=f,tr[i+1].t=1,tr[i+n+1].v=-f,tr[i+n+1].t=-1;
121     cnt=1;dfs(1);root=q[n+1];
122     q[1]=1;q[2*n+2]=2*n+2;
123     build(1,2*n+2,0);
124     m=read();
125     while(m--)
126     {
127         scanf("%s",str);
128         if(str[0]=='Q')query();
129         if(str[0]=='C')change();
130         if(str[0]=='F')add();
131     }
132     return 0;
133 }
View Code

 

splay的分裂合并【Time:19964 ms】

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 using namespace std;
  5 const int N=100010;
  6 struct node{int ch[2],fa,t,num;long long v,sum,tag;}tr[N<<1];
  7 struct edge{int next,to;}e[N];
  8 int n,m,f,root,cnt;
  9 int head[N],q[N<<1],s[N<<1];
 10 int read()
 11 {
 12     int x=0,f=1;char c=getchar();
 13     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 14     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
 15     return x*f;
 16 }
 17 void insert(int a,int b){cnt++;e[cnt].to=b;e[cnt].next=head[a];head[a]=cnt;}
 18 void dfs(int x)
 19 {
 20     q[++cnt]=x+1;
 21     for(int i=head[x];i;i=e[i].next)dfs(e[i].to);
 22     q[++cnt]=x+n+1;
 23 }
 24 void add(int x,long long tag){tr[x].sum+=tag*tr[x].num;tr[x].v+=tag*tr[x].t;}
 25 void pushup(int x)
 26 {
 27     int l=tr[x].ch[0],r=tr[x].ch[1];
 28     tr[x].num=tr[l].num+tr[r].num+tr[x].t;
 29     tr[x].sum=tr[l].sum+tr[r].sum+tr[x].v;
 30 }
 31 void pushdown(int x)
 32 {
 33     int l=tr[x].ch[0],r=tr[x].ch[1];long long tag=tr[x].tag;
 34     if(l)tr[l].tag+=tag,add(l,tag);
 35     if(r)tr[r].tag+=tag,add(r,tag);
 36     tr[x].tag=0;
 37 }
 38 void rotate(int x,int& k)
 39 {
 40     int y=tr[x].fa,z=tr[y].fa,l,r;
 41     if(tr[y].ch[0]==x)l=0;else l=1;r=l^1;
 42     if(y==k)k=x;
 43     else{if(tr[z].ch[0]==y)tr[z].ch[0]=x;else tr[z].ch[1]=x;}
 44     tr[x].fa=z;tr[y].fa=x;tr[tr[x].ch[r]].fa=y;
 45     tr[y].ch[l]=tr[x].ch[r];tr[x].ch[r]=y;
 46     pushup(y);pushup(x);
 47 }
 48 void splay(int x,int& k)
 49 {
 50     int top=0;s[++top]=x;
 51     for(int i=x;tr[i].fa;i=tr[i].fa)s[++top]=tr[i].fa;
 52     for(int i=top;i;i--)if(tr[s[i]].tag)pushdown(s[i]);
 53     while(x!=k)
 54     {
 55         int y=tr[x].fa,z=tr[y].fa;
 56         if(y!=k)
 57         {
 58             if((tr[y].ch[0]==x)^(tr[z].ch[0]==y))rotate(x,k);
 59             else rotate(y,k);
 60         }
 61         rotate(x,k);
 62     }
 63 }
 64 int find(int x){while(tr[x].ch[1])x=tr[x].ch[1];return x;}
 65 void build(int l,int r,int last)
 66 {
 67     if(l>r)return;
 68     int mid=(l+r)>>1;
 69     tr[q[mid]].fa=q[last];
 70     tr[q[last]].ch[mid>last]=q[mid];
 71     build(l,mid-1,mid);build(mid+1,r,mid);
 72     pushup(q[mid]);
 73 }
 74 int merge(int r1,int r2)
 75 {
 76     int w=find(r1);
 77     splay(w,r1);
 78     tr[w].ch[1]=r2;
 79     tr[r2].fa=w;
 80     pushup(w);
 81     return w;
 82 }
 83 void cutl(int x,int rt,int& r1,int& r2)
 84 {
 85     splay(x,rt);
 86     r1=tr[x].ch[0];r2=x;
 87     tr[x].ch[0]=0;
 88     tr[r1].fa=0;
 89     pushup(x);
 90 }
 91 void cutr(int x,int rt,int& r1,int& r2)
 92 {
 93     splay(x,rt);
 94     r1=x;r2=tr[x].ch[1];
 95     tr[x].ch[1]=0;
 96     tr[r2].fa=0;
 97     pushup(x);
 98 }
 99 void query()
100 {
101     int x=read()+1;
102     splay(x,root);
103     printf("%lld\n",tr[tr[x].ch[0]].sum+tr[x].v);
104 }
105 void change()
106 {
107     int x=read()+1,y=x+n,k=read()+1,p1,p2,p3;
108     cutl(x,root,p1,p2);
109     cutr(y,p2,p2,p3);
110     cutr(k,merge(p1,p3),p1,p3);
111     root=merge(merge(p1,p2),p3);
112 }
113 void add()
114 {
115     int x=read()+1,y=x+n;long long tag=read();
116     splay(x,root);splay(y,tr[x].ch[1]);
117     int z=tr[y].ch[0];
118     add(x,tag);add(y,tag);
119     add(z,tag);tr[z].tag+=tag;
120     pushup(y);pushup(x);
121 }
122 int main()
123 {
124     char str[5];
125     n=read();
126     for(int i=2;i<=n;i++)f=read(),insert(f,i);
127     for(int i=2;i<=n+1;i++)f=read(),tr[i].v=f,tr[i].t=1,tr[i+n].v=-f,tr[i+n].t=-1;
128     cnt=0;q[++cnt]=1;dfs(1);q[++cnt]=2*n+2;
129     build(1,2*n+2,0);root=q[n+1];
130     m=read();
131     while(m--)
132     {
133         scanf("%s",str);
134         if(str[0]=='Q')query();
135         if(str[0]=='C')change();
136         if(str[0]=='F')add();
137     }
138     return 0;
139 }
View Code
posted @ 2017-12-04 09:28  Zsnuo  阅读(360)  评论(0编辑  收藏  举报