NC14661 简单的数据结构

题目链接

题目

题目描述

栗酱有一天在网上冲浪的时候发现了一道很有意思的数据结构题。

该数据结构形如长条形。

一开始该容器为空,有以下七种操作。

1 a从前面插入元素a

2 从前面删除一个元素

3 a从后面插入一个元素

4 从后面删除一个元素

5 将整个容器头尾翻转

6 输出个数和所有元素

7 对所有元素进行从小到大排序

输入描述

只有一组数据,第一行 \(n≤50000,m≤200000, a≤100000\) 代表最大数据数目和操作次数。
接下来每一行一个操作如上描述。保证所有操作合法(不会在容器为空时删除元素)。
6、7操作共计不会超过10次。

输出描述

当执行6操作时,第一行先输出当前的个数,然后从头到尾按顺序输出,每两个元素之间用一个空格隔开,末尾不能有空格。

示例1

输入

10 9
1 1
3 5
3 4
6
4
5
6
7
6

输出

3
1 5 4
2
5 1
2
1 5

题解

知识点:STL,队列。

一道双端队列的模板题,用 stl 的 \(deque\) 能完美解决。

注意的是反转操作并非真反转,只要标记是否是反转状态,然后队头弹出/压入和队尾弹出/压入互相交换,排序用正向迭代器和反向迭代器交换就行。

stl 的双端队列存储的内存并非连续内存,是分段连续内存,在跨段时用通常会慢一些,因此时间复杂度常数比 \(vector\) 大。通常 \(queue\) 以及 \(stack\) 是继承 \(deque\) 的因此速度也是比较慢的。

时间复杂度 压入/弹出/反转 \(O(1)\) ,随机存取 \(O(1)\) ,排序 \(O(n \log n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;
    deque<int> d;
    bool rev = false;
    while (m--) {
        int op;
        cin >> op;
        if (op == 1) {
            int t;
            cin >> t;
            if (rev) d.push_back(t);
            else d.push_front(t);
        }
        else if (op == 2) {
            if (rev) d.pop_back();
            else d.pop_front();
        }
        else if (op == 3) {
            int t;
            cin >> t;
            if (rev) d.push_front(t);
            else d.push_back(t);
        }
        else if (op == 4) {
            if (rev) d.pop_front();
            else d.pop_back();
        }
        else if (op == 5) rev ^= 1;
        else if (op == 6) {
            cout << d.size() << '\n';
            if (rev) for (int j = d.size() - 1;j >= 0;j--) cout << d[j] << ' ';
            else for (int j = 0;j < d.size();j++) cout << d[j] << ' ';
            cout << '\n';
        }
        else if (op == 7) {
            if (rev) sort(d.rbegin(), d.rend());
            else sort(d.begin(), d.end());
        }
    }
    return 0;
}
posted @ 2022-07-02 14:43  空白菌  阅读(41)  评论(0编辑  收藏  举报