The method is simple, the tree is split, the interval is extracted, the flip mark is put back.
Note: For some reason, I write about the general situation where R is ignored in the topic, otherwise it is much simpler.
So I thought it was very simple to write. Ovo
The results found to be very cumbersome, and finally written to run slowly.
#include <bits/stdc++.h> #define L (t) (t)->c[0] #define R (t) (t)->c[1] #define Z (t) (L (t)->s+1) #define N 50005#define M (s+t>>1) #define U first#define v second#define int long longusing namespace std;struct edge{edge* s;i NT V;} E[n*2],*back (e), *h[n];void Add (int u,int v) {h[u]=& (*back++= (Edge) {h[u],v});h[v]=& (*back++= (Edge) {h[v],u}) ;} typedef int DS[N];D s d,p,num,size,son,top;void dfs1 (int u) {d[u]=d[p[u]]+1;size[u]=1;int s=0;for (edge* i=h[u];i;i=i- >s) if (I->v!=p[u]) {P[I->V]=U;DFS1 (i->v); Size[u]+=size[i->v];if (S<size[i->v]) s=size[son[u]= I->V];}} void dfs2 (int u) {static int tot;num[u]=++tot;if (size[u]!=1) {Top[son[u]]=top[u];d fs2 (Son[u]);} for (edge* i=h[u];i;i=i->s) if (I->v!=p[u]&&i->v!=son[u]) DFS2 (TOP[I->V]=I->V);} struct Node{int a[3],s,u,v;bool rev;node *c[2];} Tin[n],*next=tin,zinc={0,1e9},*null=&zinc,*root;int Sum (int u,int v) {return u+v;} int Min (int u,int v) {return u<v?u:v;} int Max (int u,int v) {return u<v?v:u;}Int (*f[3]) (Int,int) ={sum,min,max};int devolve (node* t) {if (t==null) return 0;if (T->rev) {L (t)->rev^=1; R (t)->rev^=1;t->rev=0;swap (L (t), R (t)); if (int u=t->u) {t->u=0; L (t)->u+=u; R (t)->u+=u;t->a[1]+=u;t->a[2]+=u;t->v+=u;t->a[0]+=u*t->s;} return Z (t);} node* Update (node* t) {devolve (L (t));d evolve (R (t)), for (int i=0;i!=3;++i) t->a[i]=f[i] (F[i] (L (t)->a[i],r (t)- >a[i]), t->v); T->s=r (t)->s+z (t); return t;} void Link (bool i,node*& t,node*& s) {node* d=t->c[i];t->c[i]=s;s=update (t), T=d;} node* splay (int v,node*& t=root) {node* d[]={null,null};while (V!=devolve (t)) {bool I=v>z (t); v-=i*z (t); if (v!= Devolve (T->c[i]) &&i==v>z (T->c[i]) {v-=i*z (t->c[i]); link (i,t,t->c[i]->c[i^1]);} Link (i,t,d[i]);} for (int i=0;i!=2;++i) {node* s=t->c[i^1];while (d[i]!=null) Link (i,d[i],s); t->c[i^1]=s;} return update (t);} node*& splay (int s,int t) {splay (s); return L (Splay (root));} node* build (int s,int t) {if (s<=t) {node* I=next++; L (i) =build (s,m-1); R (i) =build (m+1,t); return update (i);} return null;} typedef pair<int,int> vec;vec* u=new vec[n];vec* v=new vec[n];int Solve (int i,int j,vec*& u,vec*& v) {VEC **s =&u,**t=&v;for (; Top[i]!=top[j];i=p[top[i]]) {if (d[top[i]]<d[top[j])) Swap (I,J), swap (s,t); * (*s) ++=vec ( Num[top[i]],num[i]);} if (D[i]<d[j]) swap (I,J), swap (s,t); * (*s) ++=vec (Num[j],num[i]); return num[j];} void Amend (int p,int Q,int j) {Vec *s=u,*t=v;solve (p,q,s,t), while (S--! =u) splay (s->u,s->v)->u+=j;while (t--! = V) splay (t->u,t->v)->u+=j;} int query (int p,int q,int i) {int J=i^1?0:1e9;vec *s=u,*t=v;solve (p,q,s,t), while (S--! =u) J=f[i] (J,splay (s->u,s-> v)->a[i]), while (T--! =v) J=f[i] (J,splay (T->U,T->V)->a[i]); return J;} void invert (int p,int q) {int F=0;node **x,*j=null,*k=null;vec *y,*s=u,*t=v;int e=solve (p,q,s,t); if (u!=s&&v!=t &&U->U<V->V) Swap (u,v), swap (s,t); for (vec* i=u;i!=s;++i) if (i->u==e| | I->v==e) X=&j,y=i;else{f+=i->v-i->u+1;node*& A=splay (I->U,I->V); R (Splay (a->s,a)) =j;update (j=a), A=null;} for (vec* i=v;i!=t;++i) if (i->u==e| | i->v==e) x=&k,y=i;else{node*& A=splay (I->U,I->V); R (Splay (a->s,a)) =k;update (k=a), A=null;} if (vec* i=y) {if (x==&j) f+=i->v-i->u+1;node*& a=splay (I->U,I->V); R (Splay (a->s,a)) =*x;update (*x=a), A=null;} if (!f) k->rev=1;else{j->rev=1; R (Splay (j->s,j)) =k;update (j)->rev=1;k=r (Splay (f,j)); R (j) =null;update (j)->rev=1;} if (vec* i=y) {node*& a=splay (i->u,i->u-1); *x=r (Splay (i->v-i->u+1,a=*x)); R (a) =null,update (a); for (vec* i=t-1;i>=v;--i) if (i!=y) {node*& a=splay (i->u,i->u-1); K=r (Splay (i->v-i->u+1,a=k)); R (a) =null,update (a); for (vec* i=s-1;i>=u;--i) if (i!=y) {node*& a=splay (i->u,i->u-1); J=r (Splay (i->v-i->u+1,a=j)); R (a) =null,update (a);}} #undef Intint Main () {int N,m,s,t,u;char a[10];scanf ("%d%d%*d", &n,&m); Root=build (0,n+1); for (int i=1;i!=n;++i {scanf ("%d%d", &s,&t); add (s,t);} DFS1 (1);d FS2 (Top[1]=1), while (m--) {scanf ("%s%d%d", a,&s,&t), switch (a[2]) {case ' V ': Invert (s,t); Break;case ' C ': scanf ("%d", &u); amend (s,t,u); break;default:printf ("%lld\n", Query (s,t,a[2]== ' j '? 2:a[2]!= ' m '));}}}
bzoj3159: Battle tree Chain split +splay