Given a tree with a root, the following actions are provided:
1. Ask a point to the root path on the point right and
2. Modify the father of a certain point and make sure that the change is still a tree
3. Add a value to the sub-tree of a point
Sub-tree modification, LCT obviously can not do, in the wonder if someone will write adaptive top-tree ...
First we DFS get the stack out of this tree and then into the stack for the out over stack as negative
Then a point to the root of the path on the right and is from the root node into the stack position to the point of the stack and
A subtree modifies the number of stacks and stacks in a sequence, and then modifies the sequence of the subtrees tree according to the
What about the father's operation? It is obvious that splay can be used to maintain the stack sequence to move a subtrees tree in the whole sequence.
I'm done with the problem, and it's strong and powerful.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 100100using namespace Std;typedef Long long ll;struct abcd{ABCD *ls,*rs,*fa; ll Num,sum; int Sta,pos,neg; ll Add_mark; ABCD (ll X,int _sta); void Push_up (); void Push_down (); void Add (ll x);} *null=new ABCD (0,0), *root,*tree[m][2];struct edge{int to,next;} Table[m];int head[m],tot;int n,m;int A[M];ABCD:: ABCD (ll x,int _sta) {ls=rs=fa=null; num=sum=x* (_sta==1?1:-1); Sta=_sta; pos=neg=0; if (sta==1) pos++; if (sta==2) neg++; add_mark=0;} void ABCD:: Push_up () {sum=ls->sum+rs->sum+num; pos=ls->pos+rs->pos+ (sta==1); neg=ls->neg+rs->neg+ (sta==2);} void ABCD:: Push_down () {if (Add_mark) {ls->add (Add_mark); Rs->add (Add_mark); add_mark=0; }}void ABCD:: Add (ll x) {if (this==null) return; num+=x* (sta==1?1:-1); sum+=x* (Pos-neg); Add_mark+=x;} void Push_down (ABCD *x) {static ABCD *stack[m<<1]; static int top=0; for (; x!=null;x=x->fa) stack[++top]=x; while (top) stack[top--]->push_down (); }void Zig (ABCD *x) {ABCD *y=x->fa; y->ls=x->rs; x->rs->fa=y; x->rs=y; x->fa=y->fa; if (y->fa->ls==y) y->fa->ls=x; else y->fa->rs=x; y->fa=x; Y->push_up (); if (root==y) root=x;} void Zag (ABCD *x) {ABCD *y=x->fa; y->rs=x->ls; x->ls->fa=y; x->ls=y; x->fa=y->fa; if (y->fa->ls==y) y->fa->ls=x; else y->fa->rs=x; y->fa=x; Y->push_up (); if (root==y) root=x;} void Splay (ABCD *x,abcd *tar) {push_down (x); while (1) {ABCD *y=x->fa,*z=y->fa; if (Y==tar) break; if (Z==tar) {if (X==y->ls) Zig (x); else Zag (x); Break } if (X==y->ls) {if (y==z-> ls) Zig (y); Zig (x); } else {if (y==z->rs) Zag (y); Zag (x); }} x->push_up ();} abcd* Insert (ll x,int _sta) {ABCD *y=root; while (Y->rs!=null) y=y->rs; y->rs=new ABCD (X,_sta); y->rs->fa=y; Y->push_up (); Splay (Y->rs,null); return root;} abcd* find_min (ABCD *x) {while (x->ls!=null) x=x->ls; return x;} abcd* Find_max (ABCD *x) {while (x->rs!=null) x=x->rs; return x;} void Move_to_root (ABCD *x,abcd *y) {splay (x,null); ABCD *temp1=find_max (ROOT->LS); Splay (Y,null); ABCD *temp2=find_min (ROOT->RS); Splay (Temp1,null); Splay (temp2,root);} void Add (int x,int y) {table[++tot].to=y; TABLE[TOT].NEXT=HEAD[X]; Head[x]=tot;} void DFS (int x) {int i; Tree[x][0]=insert (a[x],1); for (I=head[x];i;i=table[i].next) DFS (table[i].to); Tree[x][1]=insert (a[x],2);} int main () {int i,x,y; Char p[10]; cin>>n; for (i=2;i<=n;i++) scanf ("%d", &x), ADD (x,i); for (i=1;i<=n;i++) scanf ("%d", &a[i]); root=new ABCD (19980402,3); DFS (1); Insert (19980402,4); cin>>m; for (i=1;i<=m;i++) {scanf ("%s", p); Switch (p[0]) {case ' Q ': scanf ("%d", &x); Move_to_root (Tree[1][0],tree[x][0]); printf ("%lld\n", root->rs->ls->sum); Break Case ' C ': {scanf ("%d%d", &x,&y); Move_to_root (tree[x][0],tree[x][1]); ABCD *temp=root->rs->ls; root->rs->ls=null; Root->rs->push_up (); Root->push_up (); Splay (Tree[y][0],null); Splay (Find_min (root->rs), root); root->rs->ls=temp; Temp->fa=root-> RS; Root->rs->push_up (); Root->push_up (); Break } case ' F ': scanf ("%d%d", &x,&y); Move_to_root (tree[x][0],tree[x][1]); Root->rs->ls->add (y); Break } }}
Bzoj 3786 Galaxy Explore DFS sequence +splay