题目描述
又一个学期结束了, 又积累了好多本书, 你决定好好整理一下,整理时共有三种操作, 规则如下:
1 p 表示把编号为 p 的书放到最前面
2 p 表示把编号为 p 的书放到最后面
3 p q 表示把编号为 p 的书放到编号为 q 的书的后面
1、2、3 分别代表整理操作的种类, p、q 表示书的编号,他们之间由空格分隔;
已知在整理之前,所有书从 1 开始依次编号排放。
输入格式
共 m+1 行。
第一行有两个由空格分隔的正整数 n 和 m, 分别表示 n 本书和 m 次整理操作。
接下来 m 行, 每行有 2 个或 3 个由空格分隔的正整数, 对应上述三种整理操作。
输出格式
共 1 行,经过整理后的书本顺序,书本间用空格隔开。
输入输出样例
输入样例1:
10 4
1 3
2 4
3 3 6
3 1 5
输出样例1:
2 5 1 6 3 7 8 9 10 4
说明
数据范围: 1 ≤ n,m ≤ 100000
【耗时限制】1000ms 【内存限制】128MB
-------------------------------------------------------分割线-------------------------------------------------------------
满分AC代码
cpp
#include<iostream>
#include<map>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<sstream>
#include<set>
using namespace std;
long long l[100010],r[100010];
inline void Link(int L,int R){
r[L]=R;
l[R]=L;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
l[i]=i-1;
r[i]=(i+1)%(n+1);
}
l[0]=n;
r[0]=1;
int c,x,y;
int head=1,tail=n;
int lx,rx,ly,ry;
for(int i=1;i<=m;i++){
cin>>c;
if(c==1){
cin>>x;
head=r[0];
if(x==head) continue;
lx=l[x],rx=r[x];
Link(lx,rx);
l[head]=x;
r[x]=head;
l[x]=0;
r[0]=x;
}
if(c==2){
cin>>x;
tail=l[0];
if(x==tail) continue;
if(n<=1) continue;
lx=l[x],rx=r[x];
Link(lx,rx);
r[tail]=x;
l[x]=tail;
r[x]=0;
l[0]=x;
}
if(c==3){
cin>>x>>y;
if(x==y) continue;
if(n<=1) continue;
if(r[y]==x) continue;
lx=l[x],rx=r[x];
ly=l[y],ry=r[y];
Link(lx,rx);
Link(x,ry);
Link(y,x);
}
}
int b=r[0];
for(int i=1;i<=n;i++){
cout<<b<<" ";
b=r[b];
}
return 0;
}