QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#49140#4593. Darkmoon Faireckiseki#AC ✓850ms23272kbC++4.4kb2022-09-19 15:35:102022-09-19 15:35:12

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-09-19 15:35:12]
  • 评测
  • 测评结果:AC
  • 用时:850ms
  • 内存:23272kb
  • [2022-09-19 15:35:10]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

const int mod = 998244353;

int modadd(int a, int b) {
    a += b;
    if (a >= mod) a -= mod;
    return a;
}
int modsub(int a, int b) {
    a -= b;
    if (a < 0) a += mod;
    return a;
}

const int maxn = 300025;

struct Segtree {
    int n;
    array<int,4> sum[maxn * 2];
    using Tag = array<int,2>;
    Tag tag[maxn * 2];
    void upd(int p, Tag t) {
        for (int i = 0; i < 2; i++)
            if (t[i] != -1) {
                for (int s = 0; s < 4; s++)
                    if ((s >> i & 1) != t[i]) {
                        const int ns = t[i]
                            ? (s | (1 << i))
                            : (s & ~(1 << i));
                        assert (ns != s);
                        sum[p][ns]
                            = modadd(sum[p][ns], sum[p][s]);
                        sum[p][s] = 0;
                    }
            }
        for (int i = 0; i < 2; i++)
            if (t[i] != -1)
                tag[p][i] = t[i];
    }

    void push(int p) {
        for (int h = __lg(n); h >= 0; h--) {
            int i = p >> h;
            if ((i >> 1) == 0) continue;
            if (tag[i>>1][0] == -1 && tag[i>>1][1] == -1)
                continue;
            upd(i, tag[i>>1]);
            upd(i^1, tag[i>>1]);
            tag[i>>1] = { -1, -1 };
        }
    }

    void pull(int p) {
        while (p >>= 1) {
            for (int i = 0; i < 4; i++) {
                sum[p][i]
                    = modadd(sum[p << 1][i], sum[p << 1 | 1][i]);
            }
            upd(p, tag[p]);
        }
    }

    void apply(int l, int r, Tag t) {
        // cerr << "apply " << ' ' << l << ' ' << r << ' ' << t[0] << ' ' << t[1] << endl;
        int tl = l, tr = r;
        push(l + n), push(r - 1 + n);
        for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
            if (l & 1) upd(l++, t);
            if (r & 1) upd(--r, t);
        }
        pull(tl + n), pull(tr - 1 + n);
    }

    void edit(int p, int v) {
        p += n;
        push(p);
        int s = 0;
        for (int i = 0; i < 2; i++) {
            assert (tag[p][i] != -1);
            if (tag[p][i] == 1)
                s |= 1 << i;
        }
        sum[p][s] = v;
        pull(p);
    }

    array<int,4> query() {
        push(n);
        return sum[1];
    }

    void printCol() {
        return;
        for (int i = 0; i < n; i++) {
            push(i + n);
            int s = 0;
            for (int j = 0; j < 2; j++) {
                assert (tag[i + n][j] != -1);
                if (tag[i + n][j] == 1)
                    s |= 1 << j;
            }
            cerr << bitset<2>(s) << ' ';
        }
        cerr << endl;
    }

    void init(int _n) {
        n = _n;
        for (int i = 1; i < n * 2; i++) {
            if (i < n)
                for (int j = 0; j < 2; j++)
                    tag[i][j] = -1;
            else
                for (int j = 0; j < 2; j++)
                    tag[i][j] = 0;
        }
        for (int i = 1; i < n * 2; i++) {
            for (int j = 0; j < 4; j++) {
                sum[i][j] = 0;
            }
        }
    }
} sgt;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int t; cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<int> a(n);
        for (int i = 0; i < n; i++)
            cin >> a[i];

        vector<pair<int,int>> mn, mx;
        vector<int> dp(n + 1);
        sgt.init(n + 1);
        dp[n] = 1;
        sgt.edit(n, dp[n]);
        for (int i = n - 1; i >= 0; i--) {
            while (mn.size() && mn.back().first >= a[i])
                mn.pop_back();
            while (mx.size() && mx.back().first <= a[i])
                mx.pop_back();
            {
                int l = i;
                int r = (mn.empty() ? n : mn.back().second);
                sgt.apply(l + 1, r + 1, { -1, i & 1 });
                mn.emplace_back(a[i], i);
            }
            {
                int l = i;
                int r = (mx.empty() ? n : mx.back().second);
                sgt.apply(l + 1, r + 1, { i & 1, -1 });
                mx.emplace_back(a[i], i);
            }

            // sgt.printCol();
            auto bb = sgt.query();
            // for (int j = 0; j < 4; j++)
            //     cerr << bb[j] << ' ';
            // cerr << endl;
            dp[i] = (i & 1 ? bb[1] : bb[2]);
            // cerr << "dp[i] " << i << ' ' << dp[i] << endl;
            sgt.edit(i, dp[i]);
        }

        cout << dp[0] << '\n';
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 850ms
memory: 23272kb

input:

4
300000
755900426 263585675 587172343 877004671 963559951 504355670 306164508 988722056 544618772 865338006 915826014 767023342 796004639 912685743 219928703 52575265 339635052 499642509 217247848 549649089 41848450 198239532 386065393 723588136 192758555 815017802 45197937 603499890 59518471 25526...

output:

27118667
477592178
378132727
378132727

result:

ok 4 lines