Permutation Transformer
Permutation Transformer |
Write a program to transform the permutation 1, 2, 3,..., n according to m instructions. Each instruction (a, b) means to take out the subsequence from the a-th to the b-th element, reverse it, then append it to the end.
Input
There is only one case for this problem. The first line contains two integers
n and m (1n,
m
100, 000). Each of the next
m lines contains an instruction consisting of two integers
a and b (1
a
b
n).
Output
Print n lines, one for each integer, the final permutation.
Explanation of the sample below
Instruction (2,5): Take out the subsequence {2,3,4,5}, reverse it to {5,4,3,2}, append it to the remaining permutation {1,6,7,8,9,10}
Instruction (4,8): The subsequence from the 4-th to the 8-th element of {1,6,7,8,9,10,5,4,3,2} is {8,9,10,5,4}. Take it out, reverse it, and you'll get the sample output.
Warning: Don't use cin, cout for this problem, use faster i/o methods e.g
scanf, printf.
Sample Input
10 2 2 5 4 8
Sample Output
1 6 7 3 2 4 5 10 9 8
最开始排列1-N,有M条指令,每条指令(a,b)表示取出第a-b个元素,翻转后添加到排列尾部。
用split操作把a之前的和整个串分开,再把剩下的串分成左边b-a+1个,剩下的在右边,这样就有了left,mid,right,把mid标记旋转,合并left和right,再和mid合并。
旋转就和线段树一样,这里就是swap(ch[0],ch[1]),有标记的话要pushdown。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<utility>
#include<cstring>
#include<stack>
#include<queue>
#include<map>
#include<deque>
#include<cmath>
#include<map>
#define INF 0x3f3f3f3f
#define eps 1e-3
using namespace std;
typedef long long LL;
const int MAXN=100010;
const int MAXM=1030;
const int MOD=1000000007;
int N,M;
struct Node{
Node* ch[2];
int s;
int v;
int flip;
int cmp(int k) const{
int d=k-ch[0]->s;
if(d==1) return -1;
return d<=0?0:1;
}
void maintain(){
s=ch[0]->s+ch[1]->s+1;
}
void pushdown(){
if(flip){
swap(ch[0],ch[1]);
ch[0]->flip=!ch[0]->flip;
ch[1]->flip=!ch[1]->flip;
flip=0;
}
}
};
Node* null=new Node();
void rotate(Node*& o,int d){
Node* k=o->ch[d^1];
o->ch[d^1]=k->ch[d];
k->ch[d]=o;
o->maintain();
k->maintain();
o=k;
}
void splay(Node*& o,int k){
o->pushdown();
int d=o->cmp(k);
if(d==1) k-=o->ch[0]->s+1;
if(d!=-1){
Node* p=o->ch[d];
p->pushdown();
int d2=p->cmp(k);
int k2=(d2==0?k:k-p->ch[0]->s-1);
if(d2!=-1){
splay(p->ch[d2],k2);
if(d==d2) rotate(o,d^1);
else rotate(o->ch[d],d);
}
rotate(o,d^1);
}
}
Node* merge(Node* left,Node* right){
splay(left,left->s);
left->ch[1]=right;
left->maintain();
return left;
}
//k>=1
void split(Node* o,int k,Node*& left,Node*& right){
splay(o,k);
left=o;
right=o->ch[1];
o->ch[1]=null;
left->maintain();
}
struct SplaySequence{
int n;
Node seq[MAXN];
Node* root;
Node* build(int sz){
if(!sz) return null;
Node* L=build(sz/2);
Node* o=&seq[++n];
o->v=n;
o->ch[0]=L;
o->ch[1]=build(sz-sz/2-1);
o->flip=0;
o->maintain();
return o;
}
void init(int sz){
n=0;
null->s=0;
root=build(sz);
}
};
vector<int> ans;
void print(Node* o){
if(o!=null){
o->pushdown();
print(o->ch[0]);
ans.push_back(o->v);
print(o->ch[1]);
}
}
SplaySequence ss;
int main(){
freopen("in.txt","r",stdin);
while(scanf("%d%d",&N,&M)!=EOF){
ss.init(N+1);
while(M--){
int a,b;
scanf("%d%d",&a,&b);
Node *left,*mid,*right,*o;
split(ss.root,a,left,o);
split(o,b-a+1,mid,right);
mid->flip^=1;
ss.root=merge(merge(left,right),mid);
}
print(ss.root);
for(int i=1;i<=N;i++) printf("%d\n",ans[i]-1);
}
return 0;
}