'commit'
This commit is contained in:
96
TangDou/LuoGuBook/P1160.cpp
Normal file
96
TangDou/LuoGuBook/P1160.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//双链表模板
|
||||
const int N = 100010;
|
||||
|
||||
int e[N]; //数据
|
||||
int l[N]; //左链表
|
||||
int r[N]; //右链表
|
||||
int idx; //准备放入的索引值
|
||||
|
||||
//正整数x,表示将x号同学从队列中移去,如果x号同学已经不在队列中则忽略这一条指令。
|
||||
//正是因为有了这句话,如果没有删除的标识了,真的有重复指令就会让数据出问题。
|
||||
// 因为可能重复的对左右结点进行操作,造成数据错误。
|
||||
int st[N]; //删除标识
|
||||
// 黄海写的题解
|
||||
// https://www.acwing.com/solution/content/35794/
|
||||
|
||||
//0表示头,1表示尾,正式使用的是从idx=2开始
|
||||
void init() {
|
||||
//0的右端是1,1的左端是0
|
||||
r[0] = 1, l[1] = 0, idx = 2;
|
||||
}
|
||||
|
||||
//函数含义:在k号节点右侧插入,值为x
|
||||
//如果想实现:在k号节点左侧插入,值为x 则调用:add(l[k],x),意义为在k的左侧,
|
||||
//相当于在k的左侧节点的右侧,
|
||||
void add(int k, int x) {
|
||||
e[idx] = x; //将x放入到一个空的单元格中
|
||||
l[idx] = k; //将新增加的单元格的右指针指向k的下一链路节点
|
||||
r[idx] = r[k]; //将新增加的单元格的左指针指向k
|
||||
//完成上面两步后,只是让idx这个节点建立了与原来两个节点的关系,而原来的两个k与r[k],
|
||||
// l[r[k]]还是旧的值,也需要进行修改。
|
||||
l[r[k]] = idx;
|
||||
r[k] = idx;
|
||||
//为下一次做准备
|
||||
idx++;
|
||||
}
|
||||
|
||||
//删除第k个节点
|
||||
void remove(int k) {
|
||||
r[l[k]] = r[k];
|
||||
l[r[k]] = l[k];
|
||||
}
|
||||
|
||||
int n, K, p, m, x;
|
||||
|
||||
|
||||
//输出双链表
|
||||
void print() {
|
||||
//遍历双向链表的方法
|
||||
for (int i = r[0]; i != 1; i = r[i]) cout << e[i] << " ";
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
//初始化双链表
|
||||
init();
|
||||
|
||||
//读入
|
||||
cin >> n;
|
||||
|
||||
//先将1号同学安排进队列
|
||||
//最左端就是表示在head(0号)的右侧插入一个数据
|
||||
add(0, 1);
|
||||
for (int i = 2; i <= n; i++) {
|
||||
//k为小于i的正整数
|
||||
cin >> k >> p;
|
||||
//p为0,表示将i号同学插入到k号同学的左边
|
||||
//p为1,表示将i号同学插入到k号同学的右边
|
||||
|
||||
//idx从2开始,所以下标需要k+1传入才对
|
||||
//就是1号同学的idx=2
|
||||
//就是2号同学的idx=3
|
||||
//就是3号同学的idx=4
|
||||
//就是k号同学的idx=k+1
|
||||
//右边就是正常的add(k+1,i)
|
||||
//左边稍有一点变化:add(l[k+1],i), 表示在当前号的左侧那个,就是它的前面结点的右侧放入
|
||||
if (p == 0) add(l[k + 1], i);
|
||||
else add(k + 1, i);
|
||||
}
|
||||
//表示去掉的同学数目
|
||||
cin >> m;
|
||||
for (int i = 1; i <= m; i++) {
|
||||
cin >> x;
|
||||
//表示将x号同学从队列中移去
|
||||
if (!st[x + 1]) {
|
||||
remove(x + 1);
|
||||
st[x + 1] = 1;
|
||||
}
|
||||
}
|
||||
//输出链表 (表示了队列从左到右所有同学的编号,行末换行且无空格)
|
||||
print();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user