文艺平衡树
Time Limit: 10 Sec
Memory Limit: 128 MB
Submit: 3386 Solved: 1916
Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
Output
输出一行n个数字,表示原始序列经过m次变换后的结果
Sample Input
5 3
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
Splay细节太多。。建树的时候 l>r 要return!!
然后就是注意update!!
以及最后遍历的时候注意标记下放!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int INF=0x3f3f3f3f;
const int maxn = 100005;
struct Node
{
int val;
int size;
int fa,ch[2];
bool rev;
}node[maxn];
int root;
#define val(x) node[x].val
#define size(x) node[x].size
#define fa(x) node[x].fa
#define ch(x,d) node[x].ch[d]
#define rev(x) node[x].rev
inline void update(int x)
{
int l=ch(x,0),r=ch(x,1);
size(x)=1;
if(l) size(x) += size(l);
if(r) size(x) += size(r);
}
void rotate(int x,int &to)
{
int y=fa(x),z=fa(y);
int l= ch(y,1)==x , r=l^1;
if(y==to) to = x;
else ch(z,ch(z,1)==y) = x;
fa(ch(x,r))=y; fa(y)=x; fa(x)=z;
ch(y,l)=ch(x,r); ch(x,r)=y;
update(y); update(x);
}
void splay(int x,int &to)
{
while(x^to)
{
int y=fa(x),z=fa(y);
if(y^to)
if(ch(y,0)==x ^ ch(z,0)==y) rotate(x,to);
else rotate(y,to);
rotate(x,to);
}
}
void pushdown(int x)
{
if(!rev(x)) return;
rev(x)^=1;
int l=ch(x,0),r=ch(x,1);
if(l) swap(ch(l,0),ch(l,1)),rev(l)^=1;
if(r) swap(ch(r,0),ch(r,1)),rev(r)^=1;
}
int find(int x,int k)
{
pushdown(x);
int lsize=size(ch(x,0));
if(lsize+1==k) return x;
if(k<=lsize) return find(ch(x,0),k);
else return find(ch(x,1),k-lsize-1);
}
int split(int s,int t) // original array
{
int x=find(root,s),y=find(root,t+2);
splay(x,root); splay(y,ch(x,1));
return ch(y,0);
}
void reverse(int s,int t)
{
int rt = split(s,t);
swap(ch(rt,0),ch(rt,1));
rev(rt) ^= 1;
}
int n,m;
int a[maxn];
void build(int l,int r,int f)
{
if(l>r) return; // must !! or RE!!
int m=(l+r)>>1;
if(l^r) build(l,m-1,m),build(m+1,r,m);
fa(m)=f;
ch(f,m>f)=m; // !!
val(m)=a[m];
update(m); // !!
}
void print_in(int x)
{
if(!x) return;
pushdown(x); // must !! probably to be lazyed!
print_in(ch(x,0));
if(val(x)^INF) printf("%d ",val(x));
print_in(ch(x,1));
}
int main()
{
freopen("splay.in","r",stdin);
freopen("splay.out","w",stdout);
scanf("%d%d",&n,&m);
a[1]=a[n+2]=INF;
for(int i=1;i<=n;i++) a[i+1]=i;
build(1,n+2,0);
root = (n+3)>>1;
for(int i=1;i<=m;i++)
{
int s,t;
scanf("%d%d",&s,&t);
reverse(s,t);
//print_in(root);cout<<endl;
}
print_in(root);
}