1007 Boring data structure problem (双端队列,模拟)
题意:
维护一个空队列,有无限个元素编号为1~n,按顺序进入队列,一共有四种操作
L:左边插入一个元素
R:右边插入一个元素
G x:删去元素x
Q:询问队列中间元素的序号
题解:
左右侧分别开一个队列,并且不断维护使得左右元素相等,或右边元素比左边多一个,这样中间元素即为右侧队列最前的一个元素
#include<iostream>
#include<deque>
using namespace std;
#define maxn 10000007
deque<int>lq, rq;
int tot = 0;
int vis[maxn];
int lc, rc;
void del()//每次修改长度后,维护lc==rc或lc+1==rc
{
while (lc > rc)//左边元素大于右边
{
while (vis[lq.back()] == 0)lq.pop_back();//有元素被删了pop出去
rq.push_front(lq.back());//将左侧队列的一个元素给右侧队列
lq.pop_back();
rc++;
lc--;
vis[rq.front()] = 2;//右侧元素标记为2
}
while (rc - 1 > lc) {
while (vis[rq.front()] == 0)rq.pop_front();
lq.push_back(rq.front());//将右侧队列的一个元素给左侧队列
rq.pop_front();
lc++;
rc--;
vis[lq.back()] = 1;//左侧元素标记为1
}
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--)
{
char op;
cin >> op;
if (op== 'L')
{
lq.push_front(++tot);
vis[tot] = 1;
lc++;
del();
}
if (op == 'R')
{
rq.push_back(++tot);
vis[tot] = 2;
rc++;
del();
}
if (op == 'G')
{
int x;
cin >> x;
if (vis[x] == 1) lc--;
if (vis[x] == 2) rc--;
vis[x] = 0;
del();
}
if (op == 'Q')
{
while (vis[rq.front()] == 0)rq.pop_front();
cout << rq.front()<<"\n";//输出右侧队列最前面一个元素
}
}
}