本题主要学习
1,平衡树按照区间建树
int build(int l,int r,int fa){
if(l>r){
return 0;
}
int mid=(l+r)/2;
int opt=++tot;
tre[opt].ch[0]=tre[opt].ch[1]=0;
tre[opt].fa=fa;
tre[opt].cnt++;
tre[opt].val=a[mid];
tre[opt].siz++;
tre[opt].ch[0]=build(l,mid-1,opt);
tre[opt].ch[1]=build(mid+1,r,opt);
update(opt);
return opt;
}
2,平衡树tag维护
void update(int p){
if(!p){
return;
}
tre[p].siz=tre[p1].siz+tre[p2].siz+tre[p].cnt;
}
void pushdown(int p){
if(p&&tre[p].tag){
tre[p1].tag^=1;
tre[p2].tag^=1;
swap(tre[p].ch[0],tre[p].ch[1]);
tre[p].tag=0;
}
}
3,平衡树将点旋转至目标点
void splay(int x,int k){
for(int f;(f=tre[x].fa)!=k;rotate(x)){
if(tre[f].fa!=k){
rotate(get(x)==get(f)?f:x);
}
}
if(k==0){
root=x;
}
}
平衡树把点 l-1 转到顶端 r+1 转到 l-1 右儿子,即可保证 r-1 左儿子编号均为:l-1<i<r+1,最后把r+1 左儿子交换位置就完成了翻转
完整代码
#include<bits/stdc++.h>
#define p1 tre[p].ch[0]
#define p2 tre[p].ch[1]
using namespace std;
const int F=600000;
struct sl1{
int l,r;
int tag,val,cnt,siz,fa;
int ch[2];
}tre[F];
int tot,n,m,root,top;
int a[F],sack[F];
int get(int x){
return x==tre[tre[x].fa].ch[1];
}
void update(int p){
if(!p){
return;
}
tre[p].siz=tre[p1].siz+tre[p2].siz+tre[p].cnt;
}
void pushdown(int p){
if(p&&tre[p].tag){
tre[p1].tag^=1;
tre[p2].tag^=1;
swap(tre[p].ch[0],tre[p].ch[1]);
tre[p].tag=0;
}
}
int build(int l,int r,int fa){
if(l>r){
return 0;
}
int mid=(l+r)/2;
int opt=++tot;
tre[opt].ch[0]=tre[opt].ch[1]=0;
tre[opt].fa=fa;
tre[opt].cnt++;
tre[opt].val=a[mid];
tre[opt].siz++;
tre[opt].ch[0]=build(l,mid-1,opt);
tre[opt].ch[1]=build(mid+1,r,opt);
update(opt);
return opt;
}
/*inline void rotate(int x){
int fnow=tre[x].fa,ffnow=tre[fnow].fa;
pushdown(x),pushdown(fnow);
bool w=get(x);
tre[fnow].ch[w]=tre[x].ch[w^1];
tre[tre[fnow].ch[w]].fa=fnow;
tre[fnow].fa=x;
tre[x].fa=ffnow;
tre[x].ch[w^1]=fnow;
if(ffnow){
tre[ffnow].ch[tre[ffnow].ch[1]==fnow]=x;
}
update(fnow);
}*/
void rotate(int p){
int y=tre[p].fa;
int z=tre[y].fa;
pushdown(p);
pushdown(y);
int chk=get(p);
tre[y].ch[chk]=tre[p].ch[chk^1];
if(tre[p].ch[chk^1]){
tre[tre[p].ch[chk^1]].fa=y;
}
tre[p].ch[chk^1]=y;
tre[y].fa=p;
tre[p].fa=z;
if(z){
tre[z].ch[tre[z].ch[1]==y]=p;
}
update(p);
update(y);
}
void splay(int x,int k){
for(int f;(f=tre[x].fa)!=k;rotate(x)){
if(tre[f].fa!=k){
rotate(get(x)==get(f)?f:x);
}
}
if(k==0){
root=x;
}
}
int find(int x){
int p=root;
while(1){
pushdown(p);
if(x<=tre[p1].siz){
p=p1;
}
else{
x-=tre[p1].siz+1;
if(!x){
return p;
}
p=p2;
}
}
}
void dfs(int x){
pushdown(x);
if(tre[x].ch[0]){
dfs(tre[x].ch[0]);
}
if(tre[x].val!=-F&&tre[x].val!=F){
sack[++top]=tre[x].val;
}
if(tre[x].ch[1]){
dfs(tre[x].ch[1]);
}
}
void work(int x,int y){
int l=x-1,r=y+1;
int p3=find(l);
int p4=find(r);
splay(p3,0);
splay(p4,p3);
int opt=tre[root].ch[1];
opt=tre[opt].ch[0];
tre[opt].tag^=1;
}
int main(){
cin>>n>>m;
a[1]=-F;
a[n+2]=F;
for(int i=1;i<=n;i++){
a[i+1]=i;
}
root=build(1,n+2,0);
while(m--){
int x,y;
cin>>x>>y;
work(x+1,y+1);
}
/*for(int i=1;i<=tot;i++){
cout<<tre[i].val;
cout<<":"<<tre[i].ch[0]<<" "<<tre[i].ch[1]<<endl;
}*/
dfs(root);
for(int i=1;i<=top;i++){
cout<<sack[i]<<" ";
}
return 0;
}