题目背景
这是一道经典的Splay模板题——文艺平衡树。
题目描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
输入输出格式
输入格式:
第一行为n,m n表示初始序列有n个数,这个序列依次是 (1,2, \cdots n-1,n)(1,2,?n−1,n) m表示翻转操作次数
接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r \leq n 1≤l≤r≤n
输出格式:
输出一行n个数字,表示原始序列经过m次变换后的结果
输入输出样例
输入样例#1:
5 3
1 3
1 3
1 4
输出样例#1:
4 3 2 1 5
题解:打标记的splay!调了一个上午终于调出来了!继续挖坑~
代码如下:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 100010 using namespace std; struct Splay { int key[N],son[N][2],size[N],fa[N],tag[N],rt,sz,pos; inline void push_up(int x) { size[x]=size[son[x][0]]+size[son[x][1]]+1; } inline void push_down(int x) { if(!tag[x]) { return; } tag[x]=0; tag[son[x][0]]^=1; tag[son[x][1]]^=1; swap(son[x][0],son[x][1]); } inline void rotate(int x) { int y=fa[x],z=fa[y],k=(son[y][0]==x); son[z][son[z][1]==y]=x; fa[x]=z; son[y][!k]=son[x][k]; fa[son[x][k]]=y; son[x][k]=y; fa[y]=x; push_up(y); } inline void splay(int x,int goal) { for(push_down(x); fa[x]!=goal; rotate(x)) { int y=fa[x],z=fa[y]; if(z!=goal) { (son[y][0]==x)^(son[z][0]==y)?rotate(x):rotate(y); } } push_up(x); if(!goal) { rt=x; } } inline int kth(int k) { for(int x=rt;;) { push_down(x); int y=son[x][0]; if(k>size[y]+1) { k-=size[y]+1; x=son[x][1]; } else { if(k>size[y]) { return x; } else { x=y; } } } } inline void reverse(int l,int r) { if(l>r) { swap(l,r); } int x=kth(l),y=kth(r+2); splay(x,0); splay(y,x); tag[son[y][0]]^=1; } inline int build(int *a,int father,int l,int r) { if(l>r) { return 0; } int mid=(l+r)>>1,x=++sz; fa[x]=father; key[x]=a[mid]; son[x][0]=build(a,x,l,mid-1); son[x][1]=build(a,x,mid+1,r); push_up(x); return x; } inline void put(int x) { push_down(x); if(son[x][0]) { put(son[x][0]); } if(key[x]>-1e9&&key[x]<1e9) { printf("%d ",key[x]); } if(son[x][1]) { put(son[x][1]); } } } splay1; int main() { int n,m,l,r,a[100010]; scanf("%d%d",&n,&m); for(int i=2; i<=n+1; i++) { a[i]=i-1; } a[1]=-1e9; a[n+2]=1e9; splay1.rt=splay1.build(a,0,1,n+2); for(int i=1; i<=m; i++) { scanf("%d%d",&l,&r); splay1.reverse(l,r); } splay1.put(splay1.rt); }