10284 Science one yard line drive to find bug or problem solutions monotone queue segment tree RMQ

Note: just saw the title, not evaluation, so uncertain validity of the code, but the idea of ​​the algorithm is no problem

description

Students bug really is, ah, orz ...
we are able to save bug during the Spring Festival came to Shaw resolved.
Everyone has a bug, but Shaw is only one teacher ah. How to do?
So Shaw everyone by first come first served queue, one by one, for everyone to solve.
This is not early in the morning, Xiao teacher waiting for students to come to solve the bug. However, Shaw occasionally want to know the current minimum number of bug team is much bug.
sos xbug operation indicates that a student has x number of bug, and come queued Shaw resolved.
ok operation represents Shaw has solved all the bug came in the front ranks of students.
min operation represents Xiao teacher needs to know the minimum number of teams in the current line up is the number of bug bug.

Input Format

The first input line of a positive integer n, there are n represents a total operation.
The next n input lines, each line of operating.
[Restrictions]
1≤n≤10 ^ 6
bug number each person not more than 1 million.

Output Format

Min For each operation, the number of minimum output current queuing bug.
If the execution min (or ok) operation, the current team is empty, the output "So happy! No bug!" .

Sample input

7
sos 6bug
sos 7bug
min
ok
min
ok
min

Sample Output

6bug
7bug
So happy!no bug!

This problem can be monotonous road queue solved, as follows:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000100;

/**
* zifeiy: 单调队列解法
*/

queue<int> normal_que;
deque<int> min_que;
int a[maxn], n, cnt = 0;
string s;

int main() {
    cin >> n;
    while (n --) {
        cin >> s;
        if (s == "sos") {
            scanf("%dbug", &a[cnt]);
            normal_que.push(cnt);
            while (!min_que.empty()) {
                int u = min_que.back();
                if (a[u] >= a[cnt]) min_que.pop_back();
                else break;
            }
            min_que.push_back(cnt);
            cnt ++;
        }
        else if (s == "ok") {
            if (normal_que.empty()) {
                puts("So happy!No bug!");
            } else {
                int u = normal_que.front();
                normal_que.pop();
                while (!min_que.empty() && min_que.front() <= u) {
                    min_que.pop_front();
                }
            }
        }
        else {  // "min"
            if (min_que.empty()) {
                puts("So happy!No bug!");
            } else {
                cout << a[min_que.front()] << "bug" << endl;
            }
        }
    }
    return 0;
}

RMQ can also be converted into solving the problem, here I use the tree line to achieve RMQ:

#include <bits/stdc++.h>
using namespace std;
#define INF (1<<29)
const int maxn = 1000100;

/**
* 使用线段树实现RMQ的解法
*/

int minn[maxn<<2], n, m, a;
vector<int> vec;
vector<int> queries;    // 0表示sos,1表示min,2表示ok
char ch[111];

void build(int l, int r, int rt) {
    if (l == r) minn[rt] = vec[l];
    else {
        int mid = (l + r) >> 1;
        build(l, mid, rt<<1);
        build(mid+1, r, rt<<1|1);
        minn[rt] = min(minn[rt<<1], minn[rt<<1|1]);
    }
}

int query(int L, int R, int l, int r, int rt) {
    if (L <= l && r <= R) return minn[rt];
    int mid = (l + r) >> 1;
    int tmp = INF;
    if (L <= mid) tmp = min(tmp, query(L, R, l, mid, rt<<1));
    if (mid+1 <= R) tmp = min(tmp, query(L, R, mid+1, r, rt<<1|1));
    return tmp;
}

int main() {
    scanf("%d", &m);
    for (int i = 0; i < m; i ++) {
        scanf("%s", ch);
        if (strcmp(ch, "sos") == 0) {
            scanf("%dbug", &a);
            vec.push_back(a);
            queries.push_back(0);
            n ++;
        }
        else if (strcmp(ch, "min") == 0) {
            queries.push_back(1);
        }
        else {
            queries.push_back(2);
        }
    }
    build(0, n-1, 1);
    int L = 0, R = -1;

    for (int i = 0; i < m; i ++) {
        if (queries[i] == 0) R ++;
        else if (queries[i] == 2) L ++;
        else {  // 1 - min
            if (L > R) puts("So happy!no bug!");
            else printf("%dbug\n", query(L, R, 0, n-1, 1));
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/zifeiy/p/10955712.html