优良马蜂只过hack求调

P2572 [SCOI2010] 序列操作

stripe_python @ 2024-07-14 11:45:24

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

#define N 100005

class SegmentTree {
#define ls (rt << 1)
#define rs (rt << 1 | 1)

private:
    int n, hot;
    int sum[N << 4], maxc[2][N << 4], lmax[2][N << 4], rmax[2][N << 4];
    int cover[N << 4], rev[N << 4];

    inline void pushup(int rt, int ln, int rn, int lss = -1, int rss = -1) {
        lss = (lss == -1) ? ls : lss, rss = (rss == -1) ? rs : rss;
        sum[rt] = sum[lss] + sum[rss];
        for (int i = 0; i <= 1; i++) {
            lmax[i][rt] = lmax[i][lss];
            if (i == 1 && sum[lss] == ln) lmax[i][rt] += lmax[i][rss];
            else if (i == 0 && sum[lss] == 0) lmax[i][rt] += lmax[i][rss];

            rmax[i][rt] = rmax[i][rss];
            if (i == 1 && sum[rss] == rn) rmax[i][rt] += rmax[i][lss];
            else if (i == 0 && sum[rss] == 0) rmax[i][rt] += rmax[i][lss];

            maxc[i][rt] = max(rmax[i][lss] + lmax[i][rss], max(maxc[i][lss], maxc[i][rss]));
        }
    }

    inline void pushdown(int rt, int ln, int rn) {
        if (cover[rt] != -1) {
            int val = cover[rt];
            rev[rt] = 0, cover[rt] = -1;
            sum[ls] = val * ln, sum[rs] = val * rn;
            cover[ls] = cover[rs] = val, rev[ls] = rev[rs] = 0;
            maxc[val][ls] = lmax[val][ls] = rmax[val][ls] = ln;
            maxc[val ^ 1][ls] = lmax[val ^ 1][ls] = rmax[val ^ 1][ls] = 0;
            maxc[val][rs] = lmax[val][rs] = rmax[val][rs] = rn;
            maxc[val ^ 1][rs] = lmax[val ^ 1][rs] = rmax[val ^ 1][rs] = 0;
        }
        if (rev[rt]) {
            sum[ls] = ln - sum[ls], sum[rs] = rn - sum[rs];

            if (cover[ls] != -1) cover[ls] ^= 1;
            else rev[ls] ^= 1;
            if (cover[rs] != -1) cover[rs] ^= 1;
            else rev[rs] ^= 1;

            swap(maxc[0][ls], maxc[1][ls]), swap(lmax[0][ls], lmax[1][ls]), 
            swap(rmax[0][ls], rmax[1][ls]);
            swap(maxc[0][rs], maxc[1][rs]), swap(lmax[0][rs], lmax[1][rs]), 
            swap(rmax[0][rs], rmax[1][rs]);

            rev[rt] ^= 1;
        }
    }

    void build(const int* a, int l, int r, int rt) {
        if (l == r) {
            sum[rt] = a[l];
            maxc[0][rt] = lmax[0][rt] = rmax[0][rt] = (a[l] == 0);
            maxc[1][rt] = lmax[1][rt] = rmax[1][rt] = (a[l] == 1);
            return;
        }
        int mid = (l + r) >> 1;
        build(a, l, mid, ls), build(a, mid + 1, r, rs);
        pushup(rt, mid - l + 1, r - mid);
    }

    void update(int tl, int tr, const int& c, int l, int r, int rt) {
        if (tl <= l && r <= tr) {
            sum[rt] = (r - l + 1) * c, cover[rt] = c;
            maxc[c][rt] = lmax[c][rt] = rmax[c][rt] = r - l + 1;
            maxc[c ^ 1][rt] = lmax[c ^ 1][rt] = rmax[c ^ 1][rt] = 0;
            return;
        }
        int mid = (l + r) >> 1;
        pushdown(rt, mid - l + 1, r - mid);
        if (tl <= mid) update(tl, tr, c, l, mid, ls);
        if (tr > mid) update(tl, tr, c, mid + 1, r, rs);
        pushup(rt, mid - l + 1, r - mid);
    }

    void reverse(int tl, int tr, int l, int r, int rt) {
        if (tl <= l && r <= tr) {
            sum[rt] = r - l + 1 - sum[rt], rev[rt] ^= 1;
            swap(maxc[0][rt], maxc[1][rt]), swap(lmax[0][rt], lmax[1][rt]), 
            swap(rmax[0][rt], rmax[1][rt]);
            return;
        }
        int mid = (l + r) >> 1;
        pushdown(rt, mid - l + 1, r - mid);
        if (tl <= mid) reverse(tl, tr, l, mid, ls);
        if (tr > mid) reverse(tl, tr, mid + 1, r, rs);
        pushup(rt, mid - l + 1, r - mid);
    }

    int query_sum(int tl, int tr, int l, int r, int rt) {
        if (tl <= l && r <= tr) return sum[rt];
        int mid = (l + r) >> 1, res = 0;
        pushdown(rt, mid - l + 1, r - mid);
        if (tl <= mid) res += query_sum(tl, tr, l, mid, ls);
        if (tr > mid) res += query_sum(tl, tr, mid + 1, r, rs);
        return res;
    }

    int query_max(int tl, int tr, int l, int r, int rt) {
        if (tl <= l && r <= tr) return rt;
        int mid = (l + r) >> 1;
        pushdown(rt, mid - l + 1, r - mid);
        if (tl <= mid) return query_max(tl, tr, l, mid, ls);
        if (tr > mid) return query_max(tl, tr, mid + 1, r, rs);
        int ln = query_max(tl, tr, l, mid, ls), rn = query_max(tl, tr, mid + 1, r, rs), res = ++hot;
        pushup(res, mid - l + 1, r - mid, ln, rn);
        return res;
    }

public:
    SegmentTree(int _n) : n(_n), hot(_n << 2) {}
    SegmentTree(const int* a, int _n) : n(_n), hot(_n << 2) {build(a, 1, n, 1);}

    void update(int l, int r, const int& c) {update(l, r, c, 1, n, 1);}
    void reverse(int l, int r) {reverse(l, r, 1, n, 1);}
    int query_sum(int l, int r) {return query_sum(l, r, 1, n, 1);}

    int query_max(int l, int r, const int& c) {
        int res = maxc[c][query_max(l, r, 1, n, 1)];
        return hot = (n << 2), res;
    }

#undef ls
#undef rs
};

int n, q, a[N], opt, l, r;

void _main() {
    cin >> n >> q;
    for (int i = 1; i <= n; i++) cin >> a[i];
    SegmentTree sgt(a, n);
    while (q--) {
        cin >> opt >> l >> r;
        l++, r++;
        if (opt == 0) sgt.update(l, r, 0);
        else if (opt == 1) sgt.update(l, r, 1);
        else if (opt == 2) sgt.reverse(l, r);
        else if (opt == 3) cout << sgt.query_sum(l, r) << '\n';
        else if (opt == 4) cout << sgt.query_max(l, r, 1) << '\n';
    }
} signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

#ifndef ONLINE_JUDGE
#ifndef SPN_LOCAL
    freopen(".in", "r", stdin), freopen(".out", "w", stdout);
#endif
#endif

    int t = 1;
//  cin >> t;
    while (t--) _main();
    return 0;
}

|