列表

详情


NC240870. 黑鸟

描述

我还能 再一次笑和哭吗?
就算我已经 带上我的面具 否认那份回答
我还能 再一次见到你吗?
我已被忘记 也早已经失去 曾经的那个家

我逃离 这片黑夜 在诸神的黄昏
我不再为往事受困 不再为往事受困
穿越过乌云密布 看见你那一瞬
我才发现我被爱着
我被你 所拥抱着
我们相互依存 这世界只剩下 我们

————《黑鸟》阿良良木健 (侵删)
阿良良木健给了你一个操作序列,当时还有一个参数x_i

定义操作如下:

在双端队列的左端插入x_i

在双端队列的右边端插入x_i

在双端队列左边弹出一个元素

在双端队列右边弹出一个元素

现在阿良良木健也给了你q次询问L,R,对于每次询问如下:

每次询问初始有一个空的双端队列,你依次执行第个操作,然后你需要输出完成操作后,双端队列里面所有元素的和(如果完成所有操作结束后双端队列恰好为空 输出0)。

如果在任意一次操作中,对一个空的双端队列进行了弹出一个元素的操作(即),那么输出"wlwzgkd"。



输入描述

第一行两个正整数
后面n行,每行一个或两个正整数。opt_i,当还有
后面q行,每行两个正整数,表示每次询问。

输出描述

输出一共q行,每行一个数或一个字符串,第i行表示第i次询问的答案。

示例1

输入:

6 3
1 3
2 4
3
2 6
4
1 2
1 6
4 6
3 5

输出:

6
2
wlwzgkd

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 810ms, 内存消耗: 148332K, 提交时间: 2022-09-08 09:57:02

#include <bits/stdc++.h>
#define F(x, y, z) for (int x = (y); x <= (z); ++x)
#define DF(x, y, z) for (int x = (y); x >= (z); --x)
using namespace std;
typedef long long ll;
int read() {
    char ch = getchar();
    int x = 0, pd = 0;
    while (ch < '0' || ch > '9') pd |= ch == '-', ch = getchar();
    while ('0' <= ch && ch <= '9') x = x * 10 + (ch ^ 48), ch = getchar();
    return pd ? -x : x;
}
const int maxn = 300005;
int n, m;
struct Op {
    int opt, x;
} q[maxn];
int s[maxn], t[maxn][2], mn[maxn][19];
int qmn(int l, int r) {
    int g = __lg(r - l + 1);
    return min(mn[l][g], mn[r - (1 << g) + 1][g]);
}
int tot, rt[maxn], ls[maxn << 5], rs[maxn << 5], c[maxn << 5]; ll sum[maxn << 5];
void pp(int o) { c[o] = c[ls[o]] + c[rs[o]], sum[o] = sum[ls[o]] + sum[rs[o]]; }
void upd(int &o, int l, int r, int x) {
    ++tot, ls[tot] = ls[o], rs[tot] = rs[o], o = tot;
    if (l == r) { c[tot] = 1, sum[o] = q[l].x; return; }
    int mid = (l + r) >> 1;
    if (x <= mid) upd(ls[o], l, mid, x);
    else upd(rs[o], mid + 1, r, x);
    pp(o);
}
int suf, R;
ll qry(int o, int l, int r) {
    if (c[o] <= suf && r <= R) {
        suf -= c[o];
        return sum[o];
    }
    int mid = (l + r) >> 1;
    if (R <= mid) return qry(ls[o], l, mid);
    ll ret = qry(rs[o], mid + 1, r);
    if (suf) ret += qry(ls[o], l, mid);
    return ret;
}
int stk[maxn][3], top[3], len;
struct P {
    int x, y;
} p[maxn];
int py[maxn];
void pre() {
    DF(i, n, 1) {
        if (q[i].opt < 3) {
            if (!top[q[i].opt]) p[++len] = {i, n + 1};
            else p[++len] = {i, stk[top[q[i].opt]][q[i].opt]}, --top[q[i].opt];
        } else stk[++top[q[i].opt - 2]][q[i].opt - 2] = i;
    }
    sort(p + 1, p + len + 1, [](P A, P B) {
        return A.y < B.y;
    });
    DF(i, len, 1) {
        rt[i] = rt[i + 1];
        upd(rt[i], 1, n, p[i].x);
        py[i] = p[i].y;
    }
}
int main() {
    n = read(), m = read();
    F(i, 1, n) {
        s[i] = s[i - 1], q[i].opt = read();
        t[i][0] = t[i - 1][0], t[i][1] = t[i - 1][1];
        if (q[i].opt < 3) q[i].x = read(), ++s[i], ++t[i][0];
        else --s[i], ++t[i][1];
        mn[i][0] = s[i];
    }
    F(j, 1, __lg(n))
        for (int i = 1; i + (1 << j) - 1 <= n; ++i)
            mn[i][j] = min(mn[i][j - 1], mn[i + (1 << (j - 1))][j - 1]);
    pre();
    while (m--) {
        int l = read(), r = read();
        if (qmn(l, r) < s[l - 1]) {
            puts("wlwzgkd");
            continue;
        }
        int k1 = t[r][0] - t[l - 1][0], k2 = t[r][1] - t[l - 1][1], pos = upper_bound(py + 1, py + len + 1, r) - py;
        suf = k1 - k2, R = r;
        printf("%lld\n", qry(rt[pos], 1, n));
    }
    return 0;
}

上一题