Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1Input
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=nOutput
输出一行n个数字,表示原始序列经过m次变换后的结果Sample Input
5 3
1 3
1 3
1 4Sample Output
4 3 2 1 5HINT
N,M<=100000
就是一个很简单的带翻转的splay嘛.. 涨知识了0.0..
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int Maxn = 100010;
int c[Maxn][2], s[Maxn], fa[Maxn], id[Maxn], rev[Maxn];
int n, m, sz, rt;
void push_up ( int now ){
int l = c[now][0], r = c[now][1];
s[now] = s[l]+s[r]+1;
}
void push_down ( int now ){
int l = c[now][0], r = c[now][1];
if ( rev[now] ){
swap ( c[now][0], c[now][1] );
rev[l] ^= 1; rev[r] ^= 1;
rev[now] = 0;
}
}
void bulid ( int l, int r, int f ){
if ( l > r ) return;
int now = id[l], last = id[f];
if ( l == r ){
fa[now] = last; s[now] = 1;
if ( l < f ) c[last][0] = now;
else c[last][1] = now;
return;
}
int mid = ( l + r ) >> 1; now = id[mid];
bulid ( l, mid-1, mid ); bulid ( mid+1, r, mid );
fa[now] = last; push_up (mid);
if ( mid < f ) c[last][0] = now;
else c[last][1] = now;
}
int find ( int now, int rank ){
push_down (now);
int l = c[now][0], r = c[now][1];
if ( s[l]+1 == rank ) return now;
else if ( s[l] >= rank ) return find ( l, rank );
else return find ( r, rank-s[l]-1 );
}
void rotate ( int x, int &k ){
int y = fa[x], z = fa[y], l, r;
if ( c[y][0] == x ) l = 0;
else l = 1;
r = l^1;
if ( y == k ) k = x;
else {
if ( c[z][0] == y ) c[z][0] = x;
else c[z][1] = x;
}
fa[x] = z; fa[y] = x; fa[c[x][r]] = y;
c[y][l] = c[x][r]; c[x][r] = y;
push_up (y); push_up (x);
}
void splay ( int x, int &k ){
while ( x != k ){
int y = fa[x], z = fa[y];
if ( y != k ){
if ( (c[y][0]==x)^(c[z][0]==y) ) rotate ( x, k );
else rotate ( y, k );
}
rotate ( x, k );
}
}
void rever ( int l, int r ){
int x = find ( rt, l ), y = find ( rt, r+2 );
splay ( x, rt );
splay ( y, c[x][1] );
rev[c[y][0]] ^= 1;
}
int main (){
int i, j, k;
scanf ( "%d%d", &n, &m );
sz = 0;
for ( i = 1; i <= n+2; i ++ ) id[i] = ++sz;
bulid ( 1, n+2, 0 ); rt = (n+3)>>1;
for ( i = 1; i <= m; i ++ ){
int x, y;
scanf ( "%d%d", &x, &y );
rever ( x, y );
}
for ( i = 2; i <= n+1; i ++ ){
printf ( "%d ", find ( rt, i )-1 );
}
printf ( "\n" );
return 0;
}