杭电多校第九场1007模拟链表
Posted hesorchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杭电多校第九场1007模拟链表相关的知识,希望对你有一定的参考价值。
题目
题目大意:有1、2、3…无穷个数,还有一个初始为空的双端容器,四种操作:
- L操作,将下一个数插入到容器左端。
- R操作,将下一个数插入到容器左端。
- G x操作,将数x从容器中删除,保证了x在容器中。
- Q操作,查询容器中中间那个数,如果有偶数个,取右边那个。
求解
比较简单的链表模拟,写之前应该先思考一下怎么写比较简单,有时候换一种写法可以少很多特判和代码量。
置左右端两个空指针和MID,执行操作时动态维护即可。
代码
#include <bits/stdc++.h>
using namespace std;
int x;
char s[2];
const int INF = 1e9 + 7;
const int N = 2e7 + 10000;
int L[N], R[N], a[N], p[N];
//L[i] R[i]记录i的左右结点地址 a[i]记录地址i的值 p[i]记录值i的地址 a-p对称
int cnt, pos_l, pos_r, n, mid, beg;
// pos_l pos_r 表示两端的空指针 mid为答案所在的地址 cnt为下一个值 n为容器中的数的个数
void init()
{
n = 0;
pos_l = beg;
pos_r = beg + 1;
L[pos_l] = -INF;
R[pos_l] = pos_r;
L[pos_r] = pos_l;
R[pos_r] = INF;
mid = pos_r;
}
void f1()
{
if (n == 1) //删空了
{
init();
return;
}
x = p[x];
if (n & 1)
{
if (x <= mid)
mid = R[mid];
}
else
{
if (x >= mid)
mid = L[mid];
}
R[L[x]] = R[x];
L[R[x]] = L[x];
--n;
}
void f2() //L
{
++cnt;
++n;
L[R[pos_l]] = pos_l;
L[pos_l] = pos_l - 1;
L[pos_l - 1] = -INF;
R[pos_l - 1] = pos_l;
a[pos_l] = cnt;
p[cnt] = pos_l;
pos_l--;
if (n % 2 == 1)
mid = L[mid];
}
void f3() //R
{
++cnt;
++n;
R[L[pos_r]] = pos_r;
R[pos_r] = pos_r + 1;
R[pos_r + 1] = INF;
L[pos_r + 1] = pos_r;
a[pos_r] = cnt;
p[cnt] = pos_r;
pos_r++;
if (n % 2 == 0)
mid = R[mid];
}
void f4()
{
printf("%d\\n", a[mid]);
}
void solve()
{
int q;
scanf("%d", &q);
beg = 1e7 + 5;
init();
for (int i = 0; i < q; i++)
{
scanf("%s", s);
if (s[0] == 'G')
{
scanf("%d", &x);
f1();
}
else if (s[0] == 'L')
f2();
else if (s[0] == 'R')
f3();
else
f4();
}
}
int main()
{
solve();
return 0;
}
以上是关于杭电多校第九场1007模拟链表的主要内容,如果未能解决你的问题,请参考以下文章
Rikka with Game[技巧]----2019 杭电多校第九场:1005