At the beginning of the subtree operation want to tree, but after thinking about it found that the tree has no way to maintain a point to the root of the distance, and can not maintain the corresponding relationship, and later thought of the use of Dfs order, so long as the maintenance of the prefix and can quickly find a point to the root node distance, due to the change of edge So we have to use splay maintenance, this problem to pay attention to a detail, that is, every time you want to extract an interval need to find the first successor of this interval, all finished after this problem can be over the
#include <cstdio> #include <cstdlib> #include <ctime> #include <cmath> #include <cstring> #include <string> #include <iostream> #include <iomanip> #include <algorithm> using namespace
Std
typedef long Long LL;
struct Splay {splay *fa,*ls,*rs;
ll V,sum,zsize,fsize,add_mark;
BOOL PR;
Splay ();
void Push_up ();
void Add_v (ll Val);
void Push_down ();
}*null=new splay (), mempool[300000],*root;
int dfsx[300000];
int in_t[300000];
int out_t[300000];
int fir[300000];
int nex[300000]; struct Bian {int r;}
A[600000];
int topppp;
ll v[300000];
int top=0;
void Dfs (int u,int fro) {dfsx[++top]=u;
In_t[u]=top;
for (int o=fir[u];o!=0;o=nex[o]) if (A[O].R!=FRO) DFS (A[O].R,U);
Dfsx[++top]=u;
Out_t[u]=top;
} void Splay:: Push_up () {sum=ls->sum+v+rs->sum;
zsize=ls->zsize+pr+rs->zsize;
Fsize=ls->fsize+ (1-PR) +rs->fsize; } void Splay:: Push_down () {if (add_maRK) {if (ls!=null) Ls->add_v (Add_mark);
if (rs!=null) Rs->add_v (Add_mark);
add_mark=0;
}} void Splay:: Add_v (ll val) {if (pr) v+=val;
else V-=val;
sum+= (zsize-fsize) *val;
Add_mark+=val;
} splay:: Splay () {fa=ls=rs=null;
v=sum=zsize=fsize=add_mark=pr=0;
} void Right (Splay *x) {splay *y=x->fa;
y->ls=x->rs;
x->rs->fa=y;
x->rs=y;
x->fa=y->fa;
if (Y==y->fa->ls) y->fa->ls=x;
if (Y==Y->FA->RS) y->fa->rs=x;
y->fa=x;
Y->push_up ();
if (y==root) root=x;
} void Left (Splay *x) {splay *y=x->fa;
y->rs=x->ls;
x->ls->fa=y;
x->ls=y;
x->fa=y->fa;
if (Y==y->fa->ls) y->fa->ls=x;
if (Y==Y->FA->RS) y->fa->rs=x;
y->fa=x;
Y->push_up ();
if (y==root) root=x;
} void Push_down (Splay *x) {if (x->fa!=null) Push_down (X->FA);
X->push_down (); } void Splaying(Splay *x,splay *goal)
{Push_down (x);
while (1) {splay *y=x->fa;
Splay *z=y->fa;
cout<<x<< "" <<y->rs<<endl;//<<null<< "" <<endl;
if (y==goal) break;
if (z==goal) {if (X==y->ls) right (x);
else left (x);
Break
} if (X==y->ls) {if (Y==z->ls) right (y);
Right (x);
} else if (X==y->rs) {if (Y==z->rs) left (y);
Left (x);
}} x->push_up ();
} splay *maketree (int l,int r) {if (l>r) return null;
int mid=l+r>>1;
Splay *x=&mempool[mid];
if (Mid==in_t[dfsx[mid]]) {x->v=v[dfsx[mid]];
x->sum=v[dfsx[mid]];
x->pr=true;
x->zsize=1;
} else {x->v=-v[dfsx[mid]];
x->sum=-v[dfsx[mid]];
x->pr=false;
x->fsize=1; } x->ls=maketree (l,mid-1);
x->ls->fa=x;
X->rs=maketree (MID+1,R);
x->rs->fa=x;
X->push_up ();
return x;
} splay* Find_hou (splay *o) {if (o->ls!=null) return Find_hou (O->LS);
return o;
} splay* Find_qian (splay *o) {if (o->rs!=null) return Find_qian (O->RS);
return o;
} ll Find_ans (int x) {splaying (&mempool[in_t[1]],null);
Splay *mid=find_qian (ROOT->LS);
Splaying (&mempool[in_t[x]],null);
Splay *midd=find_hou (ROOT->RS);
Splaying (Mid,null);
Splaying (Midd,root);
Return root->rs->ls->sum;
} void Change (int x,int v) {splaying (&mempool[in_t[x]],null);
Splay *mid=find_qian (ROOT->LS);
Splaying (&mempool[out_t[x]],null);
Splay *midd=find_hou (ROOT->RS);
Splaying (Mid,null);
Splaying (Midd,root);
Root->rs->ls->add_v (v);
Root->rs->push_up ();
Root->push_up (); } void move_to_wz (int x,int y) {splaying (&meMpool[in_t[x]],null);
Splay *mid=find_qian (ROOT->LS);
Splaying (&mempool[out_t[x]],null);
Splay *midd=find_hou (ROOT->RS);
Splaying (Mid,null);
Splaying (Midd,root);
Splay *qie=root->rs->ls;
qie->fa=null;
root->rs->ls=null;
Root->rs->push_up ();
Root->push_up ();
Splaying (&mempool[in_t[y]],null);
Splay *middd=find_hou (ROOT->RS);
Splaying (Middd,root);
root->rs->ls=qie;
qie->fa=root->rs;
Root->rs->push_up ();
Root->push_up ();
} void Add_edge (int l,int r) {//cout<<l<< "" <<r<<endl;
A[++topppp].r=r;
NEX[TOPPPP]=FIR[L];
FIR[L]=TOPPPP;
} Char s[10];
int main () {ll n,m;
scanf ("%lld", &n);
for (int i=1;i<n;i++) {int x;
scanf ("%d", &x);
Add_edge (x,i+1);
} for (int i=1;i<=n;i++) scanf ("%lld", &v[i]);
DFS (1,0);
Root=maketree (0,top+1);
scanf ("%lld", &m); FoR (int i=1;i<=m;i++) {scanf ("%s", s);
if (s[0]== ' Q ') {int x;
scanf ("%d", &x);
printf ("%lld\n", Find_ans (x));
} else if (s[0]== ' F ') {ll x,val;
scanf ("%lld%lld", &x,&val);
Change (X,val);
} else {int x, y;
scanf ("%d%d", &x,&y);
Move_to_wz (x, y);
}
}
}