Description
A tree of n points, with an initial weight of 1 for each point. There is a Q operation for this tree, and each operation is one of the following four actions:
+ U v C: The weights of the points on the path from U to V are added to the natural number C;
-U1 v1 U2 v2: Delete the edge of the tree (U1,V1), add a new Edge (U2,V2), to ensure that the operation is still a tree;
* U v C: The weights of the points on the path from U to V are multiplied by the natural number C;
/u V: ask for the weights of the points on the path of the U to V and find the remainder of the answer for 51061.
Input
First row two integers n,q
Next n-1 line two positive integers per line u,v, describe this tree
The next Q line, each line describes an action
Output
One line for each/corresponding answer output
Sample Input
3 2
1 2
2 3
/1 1
Sample Output
4
HINT
Data size and conventions
10% Data Guarantee, 1<=n,q<=2000
Another 15% of the data is guaranteed, 1<=n,q<=5*10^4, no-operation, and the initial tree is a chain
Another 35% of the data is guaranteed, 1<=n,q<=5*10^4, no-operation
100% Data Guarantee, 1<=N,Q<=10^5,0<=C<=10^4
Source
Obviously directly LCT on the line ... You can lay the mark on the Add and multiply.
Remember to split instead of cut when calculating ... Do not delete the edges!!!
I am a fool to add and multiply the mark as a bool ... WA's 4 rounds, 233.
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define MAXN 100010#define LL unsigned int#define P 51061usingnamespace Std;Charch[3];intU,v,w;intN,m;intSta[maxn],top;structsplay{intfa,ch[2],size;BOOLRev; LL Sum,w,time,plus;} TREE[MAXN];void inch(int&X) {CharCh=getchar ();intflag=1; x=0; while(! (ch>=' 0 '&&ch<=' 9 ')) flag=ch=='-'?-1:1, Ch=getchar (); while(ch>=' 0 '&&ch<=' 9 ') x=x*Ten+ch-' 0 ', Ch=getchar (); x*=flag;}BOOLIs_root (intx) {returntree[tree[x].fa].ch[0]!=x&&tree[tree[x].fa].ch[1]!=x;}voidPUSH_UP (intx) {tree[x].sum= (tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].SUM+TREE[X].W)%P; Tree[x].size= (tree[tree[x].ch[0]].size+tree[tree[x].ch[1]].size+1)%P;}voidCalcintXintTimintPLU) {if(!x)return; tree[x].w= (TREE[X].W*TIM+PLU)%P; Tree[x].sum= (tree[x].sum*tim+plu*tree[x].size)%P; Tree[x].plus= (TREE[X].PLUS*TIM+PLU)%P; Tree[x].time= (Tree[x].time*tim)%P;}voidPush_down (intx) {if(Tree[x].rev) {tree[x].rev^=1; tree[tree[x].ch[0]].rev^=1; tree[tree[x].ch[1]].rev^=1; Swap (tree[x].ch[0],tree[x].ch[1]); }if(tree[x].time!=1|| tree[x].plus!=0) Calc (tree[x].ch[0],tree[x].time,tree[x].plus), Calc (tree[x].ch[1],tree[x].time,tree[x].plus); Tree[x].time=1; tree[x].plus=0;}voidRotintx) {intY=tree[x].fa,z=tree[y].fa,l,r; L= (tree[y].ch[1]==X); r=l^1;if(!is_root (y)) tree[z].ch[tree[z].ch[1]==y]=x; Tree[tree[x].ch[r]].fa=y;tree[y].fa=x;tree[x].fa=z; Tree[y].ch[l]=tree[x].ch[r];tree[x].ch[r]=y; Push_up (y);p ush_up (x);}voidSplay (intx) {sta[++top]=x; for(inti=x;! Is_root (i); i=tree[i].fa) Sta[++top]=tree[i].fa; while(top) Push_down (sta[top--]); while(!is_root (x)) {intY=TREE[X].FA,Z=TREE[Y].FA;if(!is_root (y)) {if(tree[y].ch[0]==x^tree[z].ch[0]==y) rot (x);ElseRot (y); } rot (x); }}voidAccessintx) { for(intI=0; x;i=x,x=tree[x].fa) splay (x), tree[x].ch[1]=I,PUSH_UP (x);}voidMake_root (intx) {access (x); Splay (x); tree[x].rev^=1;}voidLinkintXintY) {make_root (x); tree[x].fa=y;}voidSplitintXintY//In order to obtain information to remove the subtree but not to delete the edge!!!{make_root (y); access (x); Splay (x);}voidCutintXintY) {make_root (x); Access (y); Splay (y); tree[y].ch[0]=tree[x].fa=0;}intMain () {inch(n);inch(m); for(intI=1; i<=n;i++) tree[i].w=tree[i].sum=tree[i].size=tree[i].time=1; for(intI=1; i<n;i++) {inch(u);inch(v); Link (u,v); } while(m--) {scanf ('%s ', ch);inch(u);inch(v);if(ch[0]==' + ')inch(w), Split (U,v), Calc (U,1, W);if(ch[0]=='-') Cut (U,V),inch(u),inch(v), link (u,v);if(ch[0]==' * ')inch(w), Split (U,v), Calc (u,w,0);if(ch[0]=='/') Split (U,v), printf ("%u\n", tree[u].sum); }}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
"BZOJ2631" tree