2021杭电多校第九场 1007——Boring data structure problem

题目大意

题如其名
有一个双端队列,进行 n n n 次操作,有四种操作
L : L: L:在队首插入一个数 t o t tot tot
R : R: R:在队尾插入一个数 t o t tot tot
G x G x Gx删除队列中的数 x x x
Q : Q: Q:问你队列中最中间的数是什么

解题思路

用数组模拟链表,数据有 1 e 7 1e7 1e7,可能接受不了很大的常数,我们需要开5个数组
m p : mp: mp:用来映射数的下标
l : l: l:前一个数的下标
r : r: r:后一个数的下标
a c c : acc: acc:在最中间的数的左侧还是右侧
l s : ls: ls:存数的数组
模拟一下就可以了

Code

#include <bits/stdc++.h>
#define ll long long
#define qc ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define fi first
#define se second
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define pb push_back
using namespace std;
const int MAXN = 1e7 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int ls[MAXN], l[MAXN], r[MAXN], mp[MAXN], acc[MAXN];
void solve(){
    int n;
    int pmid = 0;
    scanf("%d",&n);
    int lp = 0, rp = 0;
    int cnt = 0;
    int idx = 1;
    int num = 0;
    while(n--){
        char c[2];
        scanf("%s",c);
        if(c[0] == 'L'){
            ls[++cnt] = idx;
            mp[idx] = cnt;
            idx++;
            num++;
            if(num == 1){
                lp = rp = cnt;
                l[cnt] = r[cnt] = 0;
                pmid = cnt;
                acc[cnt] = -2;
            }
            else{
                r[cnt] = lp;
                l[lp] = cnt;
                lp = cnt;
                if(num&1){
                    acc[pmid] = 1;
                    pmid = l[pmid];
                    acc[pmid] = -2;
                }
                acc[cnt] = -1;
            }
        }
        else if(c[0] == 'R'){
            ls[++cnt] = idx;
            mp[idx] = cnt;
            idx++;
            num++;
            if(num == 1){
                lp = rp = cnt;
                l[cnt] = r[cnt] = 0;
                pmid = cnt;
                acc[pmid] = -2;
            }
            else{
                l[cnt] = rp;
                r[rp] = cnt;
                rp = cnt;
                if(num % 2 == 0){
                    acc[pmid] = -1;
                    pmid = r[pmid];
                    acc[pmid] = -2;
                }
                    acc[cnt] = 1;
            }
        }
        else if(c[0] == 'G'){
            int x;
            scanf("%d",&x);
            int k = mp[x];
            if(acc[k] == -2){
                if(num&1){
                    pmid = r[k];
                    acc[r[k]] = -2;
                }
                else{
                    pmid = l[k];
                    acc[l[k]] = -2;
                }
                if(k == lp){
                    lp = r[lp];
                }
                else if(k == rp){
                    rp = l[rp];
                }
                r[l[k]] = r[k];
                l[r[k]] = l[k];
                l[k] = 0;
                r[k] = 0;
                num--;
            }
            else if(acc[k] == -1){
                if(k == lp){
                    lp = r[lp];
                }
                if(num&1){
                    acc[pmid] = -1;
                    pmid = r[pmid];
                    acc[pmid] = -2;
                    r[l[k]] = r[k];
                    l[r[k]] = l[k];
                    l[k] = 0;
                    r[k] = 0;
                }
                else{
                    r[l[k]] = r[k];
                    l[r[k]] = l[k];
                    l[k] = 0;
                    r[k] = 0;
                }
                num--;
            }
            else if(acc[k] == 1){
                if(k == rp) rp = l[rp];
                if(num&1){
                    r[l[k]] = r[k];
                    l[r[k]] = l[k];
                    l[k] = 0;
                    r[k] = 0;
                }
                else{
                    acc[pmid] = 1;
                    pmid = l[pmid];
                    acc[pmid] = -2;
                    r[l[k]] = r[k];
                    l[r[k]] = l[k];
                    l[k] = 0;
                    r[k] = 0;
                }
                num--;
            }
        }
        else{
            printf("%d\n",ls[pmid]);
        }
    }
}

int main()
{
    #ifdef ONLINE_JUDGE
    #else
       freopen("in.txt", "r", stdin);
       freopen("out.txt", "w", stdout);
    #endif

    // qc;
    int T;
    // cin >> T;
    T = 1;
    while(T--){

        solve();
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值