Загрузка данных


#include <iostream>
using namespace std;

//СТРУКТУРА СТЕКА (массив + индекс вершины)

struct Stack {
    int data[1000000];   // массив элементов
    int topIndex;        // индекс вершины (-1 если пуст)
};

// Инициализация стека
void initStack(Stack& s) {
    s.topIndex = -1;
}

// Добавить в стек
void push(Stack& s, int x) {
    s.data[++s.topIndex] = x;
}

// Удалить вершину
void pop(Stack& s) {
    if (s.topIndex >= 0) s.topIndex--;
}

// Взять вершину (без удаления)
int top(Stack& s) {
    return s.data[s.topIndex];
}

// СТРУКТУРА ДЕКА (циклический буфер)

struct Deque {
    int data[1000000];
    int head, tail;
};

void initDeque(Deque& d) {
    d.head = 0;
    d.tail = 0;
}

void push_back(Deque& d, int x) {
    d.data[d.tail] = x;
    d.tail = (d.tail + 1) % 1000000;
}

void push_front(Deque& d, int x) {
    d.head = (d.head - 1 + 1000000) % 1000000;
    d.data[d.head] = x;
}

void pop_back(Deque& d) {
    d.tail = (d.tail - 1 + 1000000) % 1000000;
}

void pop_front(Deque& d) {
    d.head = (d.head + 1) % 1000000;
}

int front(Deque& d) {
    return d.data[d.head];
}

int back(Deque& d) {
    return d.data[(d.tail - 1 + 1000000) % 1000000];
}


// Доступ по индексу (индексация)
int get(Deque& d, int index) {
    return d.data[(d.head + index) % 1000000];
}

// ЗАДАЧА D – СТЕК С МИНИМУМОМ

void taskD() {
    int q;
    cin >> q;

    Stack st, minSt;
    initStack(st);
    initStack(minSt);

    for (int i = 0; i < q; i++) {
        int type;
        cin >> type;

        if (type == 1) {
            int x;
            cin >> x;
            push(st, x);
            // обновляем стек минимумов
            if (empty(minSt)) {
                push(minSt, x);
            } else {
                int curMin = top(minSt);
                push(minSt, x < curMin ? x : curMin);
            }
        } else if (type == 2) {
            cout << top(st) << "\n";
            pop(st);
            pop(minSt);
        } else if (type == 3) {
            cout << top(minSt) << "\n";
        }
    }
}

// ЗАДАЧА E – ОЧЕРЕДЬ С МИНИМУМОМ И ДОСТУПОМ ПО ИНДЕКСУ

void taskE() {
    int q;
    cin >> q;

    Deque dq, minDq;
    initDeque(dq);
    initDeque(minDq);

    for (int i = 0; i < q; i++) {
        int type;
        cin >> type;

        if (type == 1) {
            int x;
            cin >> x;
            push_back(dq, x);
            // поддержка монотонного дека минимумов
            while (!empty(minDq) && back(minDq) >= x) {
                pop_back(minDq);
            }
            push_back(minDq, x);
        } else if (type == 2) {
            cout << front(dq) << "\n";
            if (front(dq) == front(minDq)) {
                pop_front(minDq);
            }
            pop_front(dq);
        } else if (type == 3) {
            int idx;
            cin >> idx;
            cout << get(dq, idx - 1) << "\n";
        } else if (type == 4) {
            cout << front(minDq) << "\n";
        }
    }
}

// 5. ГЛАВНАЯ ФУНКЦИЯ

int main() {
}