题干:
一个学校里老师要将班上 NN 个同学排成一列,同学被编号为 1∼N,他采取如下的方法:
-
先将 11 号同学安排进队列,这时队列中只有他一个人;
-
2∼N 号同学依次入列,编号为 ii 的同学入列方式为:老师指定编号为 ii 的同学站在编号为1∼(i−1) 中某位同学(即之前已经入列的同学)的左边或右边;
-
从队列中去掉 MM 个同学,其他同学位置顺序不变。
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。
输入要求:
第一行一个整数 NN,表示了有 NN 个同学。
第 2\sim N2∼N 行,第 ii 行包含两个整数 k,pk,p,其中 kk 为小于 ii 的正整数,pp 为 00 或者 11。若 pp 为 00,则表示将 ii 号同学插入到 kk 号同学的左边,pp 为 11 则表示插入到右边。
第 N+1N+1 行为一个整数 MM,表示去掉的同学数目。
接下来 MM 行,每行一个正整数 xx,表示将 xx 号同学从队列中移去,如果 xx 号同学已经不在队列中则忽略这一条指令。
输出要求:
一行,包含最多 NN 个空格隔开的整数,表示了队列从左到右所有同学的编号。
输入样例:
4
1 0
2 1
1 0
2
3
3
输出样例:
2 4 1
样例解释:
将同学 22 插入至同学 11 左边,此时队列为:
2 1
将同学 33 插入至同学 22 右边,此时队列为:
2 3 1
将同学 44 插入至同学 11 左边,此时队列为:
2 3 4 1
将同学 33 从队列中移出,此时队列为:
2 4 1
同学 33 已经不在队列中,忽略最后一条指令
最终队列:
2 4 1
数据范围:
对于 20\%20% 的数据,1\leq N\leq 101≤N≤10。
对于 40\%40% 的数据,1\leq N\leq 10001≤N≤1000。
对于 100\%100% 的数据,1<M\leq N\leq 10^51<M≤N≤105。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int head=-1,nxt[N],pre[N];
void add_head(int x)
{
nxt[x]=head;
pre[x]=-1;
if(head!=-1)pre[head]=x;
head=x;
}
void add_L(int x,int y)
{
nxt[y]=x;
pre[y]=pre[x];
if(pre[x]==-1)head=y;
else nxt[pre[x]]=y;
pre[x]=y;
}
void add_R(int x,int y)
{
nxt[y]=nxt[x];
pre[y]=x;
if(nxt[x]!=-1)pre[nxt[x]]=y;
nxt[x]=y;
}
void del(int x)
{
if(pre[x]==-1)head=nxt[x];
else nxt[pre[x]]=nxt[x];
if(nxt[x]!=-1)pre[nxt[x]]=pre[x];
nxt[x]=pre[x]=x;
}
int main()
{
int n;
scanf("%d",&n);
add_head(1);
for(int i=2;i<=n;++i)
{
int k,p;scanf("%d%d",&k,&p);
if(p==0)add_L(k,i);
else add_R(k,i);
}
int m;
scanf("%d",&m);
while(m--)
{
int x;
scanf("%d",&x);
del(x);
}
for(int j=head;j!=-1;j=nxt[j])
printf("%d ",j);
return 0;
}