题目背景
这是一道经典的Splay模板题——文艺平衡树。
题目描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
输入输出格式
输入格式:
第一行为n,m
n表示初始序列有n个数,这个序列依次是 (1,2,⋯n−1,n)
m表示翻转操作次数
接下来m行每行两个数 [l,r] 数据保证 1≤l≤r≤n
输出格式:
输出一行n个数字,表示原始序列经过m次变换后的结果
输入输出样例
输入样例#1:
5 3
1 3
1 3
1 4
输出样例#1:
4 3 2 1 5
说明
n,m≤100000
每次写数据结构都要调试一万年
加两个哨兵结点0,n+1,
每次伸展把root伸展到第r+2个,root->ch[0]伸展到第l个。
下面是代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int N=100010,inf=10000010;
int n,m;
struct node
{
node* ch[2];
int laz,s,v;
node(int v):v(v){s=1;ch[0]=ch[1]=NULL;laz=0;}
int cmp(int &k)
{
int ss=(ch[0] == NULL ? 0 : ch[0]->s);
if(k == ss+1) return -1;
if(k > ss) {k-=ss+1;return 1;}
return 0;
}
void maintain(){
s=1;
if(ch[0]!=NULL) s+=ch[0]->s;
if(ch[1]!=NULL) s+=ch[1]->s;
}
void pushdown()
{
if(laz)
{
swap(ch[0],ch[1]);
if(ch[0]!=NULL) ch[0]->laz^=1;
if(ch[1]!=NULL) ch[1]->laz^=1;
laz=0;
}
}
};
node* rt=NULL;
void rot(node* &o,int d)
{
o->pushdown();node* k=o->ch[d^1];
k->pushdown();o->ch[d^1]=k->ch[d];k->ch[d]=o;
o->maintain();k->maintain();o=k;
}
void splay(node* &o,int k)
{
if(o == NULL) return ;
o->pushdown();
int d=o->cmp(k);
if(d != -1)
{
node* p=o->ch[d];if(p == NULL) return ;
p->pushdown();
int k2=k,d2=p->cmp(k2);
if(d2 != -1)
{
splay(p->ch[d2],k2);
if(d == d2) rot(o,d^1);
else rot(o->ch[d],d);
}
rot(o,d^1);
}
}
void ins(node* &o,int x)
{
if(o == NULL){o=new node(x);return ;}
int d=(x < o->v ? 0 : 1);ins(o->ch[d],x);
o->maintain();
}
void rev(int l,int r)
{
splay(rt,r+2);
splay(rt->ch[0],l);
if(rt->ch[0]->ch[1] != NULL)
rt->ch[0]->ch[1]->laz^=1;
}
int read()
{
int out=0,f=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')
{out=(out<<1)+(out<<3)+c-'0';c=getchar();}
return out*f;
}
void print(node* o)
{
if(o==NULL) return ;
o->pushdown();
print(o->ch[0]);
if(o->v != n+1 && o->v)printf("%d ",o->v);
print(o->ch[1]);
}
void solve()
{
n=read();m=read();
for(int i=1;i<=n+2;i++) {ins(rt,i-1);splay(rt,i);}
while(m--)
{
int l=read(),r=read();
rev(l,r);
}
print(rt);
}
int main()
{
solve();
return 0;
}