标签:
方法很简单,树剖,把区间提取出来,打翻转标记,再放回去。
注意:由于某种原因,我写的是把题目中的r忽略掉的一般情况,否则简单得多。
于是本以为写起来也很简单ovo
结果发现非常繁琐,最后写得又长跑得又慢。
#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 long
using namespace std;
struct edge{
edge* s;
int 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];
ds 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];
dfs2(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));
devolve(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(
t-s+2,R(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 int
int 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);
dfs2(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‘));
}
}
}
标签:
原文地址:http://www.cnblogs.com/f321dd/p/5625524.html