求助,TLE30分

P2572 [SCOI2010] 序列操作

String27 @ 2024-07-09 17:51:23

#include <iostream>
#include <algorithm>
using namespace std;

struct Node {
    int first, last;
    int len;
    int sum;        //the number of 1 in this node
    int value[3];
    int lmax[3];
    int rmax[3];
    int lazyTag;
    int reversed;
};

const int N = 1e6 + 5;

int n, m;
int a[N];
Node tree[N << 2];
/*
void debug(int p)
{
    cerr << "test:\n";
    cerr << tree[p].first << ' ' << tree[p].last << ' ' << tree[p].len << ' ' << tree[p].sum << ' ';
    cerr << tree[p].value[1] << ' ' << tree[p].lmax[1] << ' ' << tree[p].rmax[1] << ' ' << tree[p].lazyTag << ' ' << tree[p].reversed << '\n';
}
*/
void maintain(int p)
{
    tree[p].sum = tree[p << 1].sum + tree[p << 1 | 1].sum;
    for (int i = 0; i < 2; i++) {
        tree[p].lmax[i] = tree[p << 1].lmax[i] + (tree[p << 1].lmax[i] == tree[p << 1].last - tree[p << 1].first + 1 ? tree[p << 1 | 1].lmax[i] : 0);
        tree[p].rmax[i] = tree[p << 1 | 1].rmax[i] + (tree[p << 1 | 1].rmax[i] == tree[p << 1 | 1].last - tree[p << 1 | 1].first + 1 ? tree[p << 1].rmax[i] : 0);
        tree[p].value[i] = max(max(tree[p << 1].value[i], tree[p << 1 | 1].value[i]), tree[p << 1].rmax[i] + tree[p << 1 | 1].lmax[i]);
    }
}

void pushDown(int p)
{
    if (~tree[p].lazyTag) {
        int tmp = tree[p].lazyTag;
        //set the tags
        tree[p << 1].lazyTag = tree[p << 1 | 1].lazyTag = tree[p].lazyTag;
        tree[p].lazyTag = -1;
        tree[p].reversed = tree[p << 1].reversed = tree[p << 1 | 1].reversed = 0;
        //update the number of 1 in lson and rson
        tree[p << 1].sum = tree[p << 1].len * tmp;
        tree[p << 1 | 1].sum = tree[p << 1 | 1].len * tmp;
        //update the other variables
        for (int i = 0; i < 2; i++) {
            tree[p << 1].value[i] = tree[p << 1].lmax[i] = tree[p << 1].rmax[i] = tree[p << 1].len * (i == tmp);
            tree[p << 1 | 1].value[i] = tree[p << 1 | 1].lmax[i] = tree[p << 1 | 1].rmax[i] = tree[p << 1 | 1].len * (i == tmp);
        }
    }
    if (tree[p].reversed) {
        //set the tags
        tree[p].reversed = 0;
        if (~tree[p << 1].lazyTag) {
            //if the tag of lson does not equal to -1
            //reverse the tag
            tree[p << 1].lazyTag ^= 1;
        } else {
            //the tag of lson equals to -1
            //set the reverse tag
            tree[p << 1].reversed ^= 1;
        }
        if (~tree[p << 1 | 1].lazyTag) {
            tree[p << 1 | 1].lazyTag ^= 1;
        } else {
            tree[p << 1 | 1].reversed ^= 1;
        }
        //reverse the sum tag
        tree[p << 1].sum = tree[p << 1].len - tree[p << 1].sum;
        tree[p << 1 | 1].sum = tree[p << 1 | 1].len - tree[p << 1 | 1].sum;
        //reverse the other variables
        swap(tree[p << 1].value[0], tree[p << 1].value[1]);
        swap(tree[p << 1].lmax[0], tree[p << 1].lmax[1]);
        swap(tree[p << 1].rmax[0], tree[p << 1].rmax[1]);
        swap(tree[p << 1 | 1].value[0], tree[p << 1 | 1].value[1]);
        swap(tree[p << 1 | 1].lmax[0], tree[p << 1 | 1].lmax[1]);
        swap(tree[p << 1 | 1].rmax[0], tree[p << 1 | 1].rmax[1]);
    }
}

void build(int l, int r, int p)
{
    tree[p].first = l;
    tree[p].last = r;
    tree[p].len = r - l + 1;
    tree[p].lazyTag = -1;
    if (l == r) {
        tree[p].value[a[l]] = tree[p].lmax[a[l]] = tree[p].rmax[a[l]] = 1;
        if (a[l]) {
            tree[p].sum = 1;
        }
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, p << 1);
    build(mid + 1, r, p << 1 | 1);
    maintain(p);
}

void modify(int l, int r, int p, int op)
{
    if (tree[p].first > r || tree[p].last < l) {
        return;
    }
    pushDown(p);
    if (l <= tree[p].first && tree[p].last <= r) {
        if (op < 2) {
            //set the lazy tag
            tree[p].lazyTag = op;
            //set the other variables
            tree[p].sum = tree[p].len * op;
            for (int i = 0; i < 2; i++) {
                tree[p].value[i] = tree[p].lmax[i] = tree[p].rmax[i] = tree[p].len * (i == op);
            }
        } else {
            //set the reversed tag
            if (~tree[p].lazyTag) {
                tree[p].lazyTag ^= 1;
            } else {
                tree[p].reversed ^= 1;
            }
            //reverse the other variables
            tree[p].sum = tree[p].len - tree[p].sum;
            swap(tree[p].value[0], tree[p].value[1]);
            swap(tree[p].lmax[0], tree[p].lmax[1]);
            swap(tree[p].rmax[0], tree[p].rmax[1]);
        }
//        debug(p);
        return;
    }
    modify(l, r, p << 1, op);
    modify(l, r, p << 1 | 1, op);
    maintain(p);
//    debug(p);
}

int query(int l, int r, int p, int op) {
    if (tree[p].first > r || tree[p].last < l) {
        return 0;
    }
//    cerr << "query ";
//    debug(p);
    pushDown(p);

    if (op == 3) {
        if (l <= tree[p].first && tree[p].last <= r) {
            return tree[p].sum;
        }

        return query(l, r, p << 1, op) + query(l, r, p << 1 | 1, op);

    } else {

        int lenL = query(l, r, p << 1, op);
        int lenR = query(l, r, p << 1 | 1, op);

        int lenM = 0;
        if (l <= tree[p << 1].last && tree[p << 1 | 1].first <= r) {
            lenM = min(tree[p << 1].last - l + 1, tree[p << 1].rmax[1]) + min(r - tree[p << 1 | 1].first + 1, tree[p << 1 | 1].lmax[1]);
        }
        return max(max(lenL, lenR), lenM);
    }

}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    build(1, n, 1);
    for (int i = 1; i <= m; i++) {
        int op, x, y;
        cin >> op >> x >> y;
        x++;
        y++;
        if (op <= 2) {
            modify(x, y, 1, op);
        } else {
            cout << query(x, y, 1, op) << '\n';
        }
    }
    return 0;
}

rt,线段树不知道为什么TLE了


|