10分求dalao调

P2572 [SCOI2010] 序列操作

chenwenmo @ 2024-07-16 08:49:48

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m;
int a[N];

struct tree{
    int len;
    int l, r;
    int t1, t2;//t1修改, t2取反 
    int s0, s1;
    int m0, m1, l0, r0, l1, r1;
};
tree t[N * 4];

void push_up(int x){
    tree l = t[x * 2], r = t[x * 2 + 1];
    t[x].len = l.len + r.len;
    t[x].s0 = l.s0 + r.s0;
    t[x].s1 = l.s1 + r.s1;
    t[x].l1 = l.s0 ? l.l1 : l.s1 + r.l1;
    t[x].r1 = r.s0 ? r.r1 : r.s1 + l.r1;
    t[x].l0 = l.s1 ? l.l0 : l.s0 + r.l0;
    t[x].r0 = r.s1 ? r.r0 : r.s0 + l.r0;
    t[x].m1 = max(l.l1, max(l.r1 + r.l1, r.r1));
    t[x].m0 = max(l.l0, max(l.r0 + r.l0, r.r0));
}

void push_down(int x){
    int l = x * 2, r = x * 2 + 1;
    if(t[x].t1 == 0){
        t[l].t1 = t[r].t1 = 0;
        t[l].s1 = t[l].m1 = t[l].r1 = t[l].l1 = t[r].s1 = t[r].m1 = t[r].r1 = t[r].l1 = 0;
        t[l].s0 = t[l].m0 = t[l].l0 = t[l].r0 = t[l].len;
        t[r].s0 = t[r].m0 = t[r].l0 = t[r].r0 = t[r].len;
        t[l].t2 = t[r].t2 = 0;
    }
    if(t[x].t1 == 1){
        t[l].t1 = t[r].t1 = 1;
        t[l].s0 = t[l].m0 = t[l].r0 = t[l].l0 = t[r].s0 = t[r].m0 = t[r].r0 = t[r].l0 = 0;
        t[l].s1 = t[l].m1 = t[l].l1 = t[l].r1 = t[l].len;
        t[r].s1 = t[r].m1 = t[r].l1 = t[r].r1 = t[r].len;
        t[l].t2 = t[r].t2 = 0;
    }
    if(t[x].t2 == 1){
        t[l].t2 ^= 1;
        t[r].t2 ^= 1;
        swap(t[l].s1, t[l].s0);
        swap(t[l].m1, t[l].m0);
        swap(t[l].l1, t[l].l0);
        swap(t[l].r1, t[l].r0);
        swap(t[r].s1, t[r].s0);
        swap(t[r].m1, t[r].m0);
        swap(t[r].l1, t[r].l0);
        swap(t[r].r1, t[r].r0);
    }
    t[x].t1 = -1;
    t[x].t2 = 0;
}

void build(int x, int l, int r){
    t[x].l = l, t[x].r = r;
    t[x].t1 = -1;
    if(l == r){
        t[x].len = 1;
        t[x].m1 = t[x].s1 = t[x].l1 = t[x].r1 = a[l];
        t[x].m0 = t[x].s0 = t[x].l0 = t[x].r0 = !a[l];
        return;
    }
    int mid = l + r >> 1;
    build(x * 2, l, mid);
    build(x * 2 + 1, mid + 1, r);
    push_up(x);
}

void update(int x, int l, int r, int op){
    if(t[x].l >= l && t[x].r <= r){
        if(op == 0){
            t[x].t2 = 0;
            t[x].t1 = 0;
            t[x].s1 = t[x].m1 = t[x].r1 = t[x].l1 = 0;
            t[x].s0 = t[x].m0 = t[x].l0 = t[x].r0 = t[x].len;
        }else if(op == 1){
            t[x].t2 = 0;
            t[x].t1 = 1;
            t[x].s1 = t[x].m1 = t[x].r1 = t[x].l1 = t[x].len;
            t[x].s0 = t[x].m0 = t[x].l0 = t[x].r0 = 0;
        }else{
            t[x].t2 ^= 1;
            swap(t[x].s1, t[x].s0);
            swap(t[x].m1, t[x].m0);
            swap(t[x].l1, t[x].l0);
            swap(t[x].r1, t[x].r0);
        }
        return;
    }
    push_down(x);
    int mid = t[x].l + t[x].r >> 1;
    if(l <= mid) update(x * 2, l, r, op);
    if(r > mid) update(x * 2 + 1, l, r, op);
    push_up(x);
}

int query1(int x, int l, int r){
    if(t[x].l >= l && t[x].r <= r){
        return t[x].s1;
    }
    push_down(x);
    int mid = t[x].l + t[x].r >> 1, ans = 0;
    if(l <= mid) ans += query1(x * 2, l, r);
    if(r > mid) ans += query1(x * 2 + 1, l, r);
    return ans;
}

tree query2(int x, int l, int r){
    if(t[x].l >= l && t[x].r <= r){
        return t[x];
    }
    int mid = t[x].l + t[x].r >> 1;
    push_down(x); 
    if(r <= mid) return query2(x * 2, l, r);
    else if(l > mid) return query2(x * 2 + 1, l, r);
    else{
        tree ans, a = query2(x * 2, l, r), b = query2(x * 2 + 1, l, r);
        ans.s0 = a.s0 + b.s0;
        ans.s1 = a.s1 + b.s1;
        ans.l1 = a.s0 ? a.l1 : a.s1 + b.l1;
        ans.r1 = b.s0 ? b.r1 : b.s1 + a.r1;
        ans.l0 = a.s1 ? a.l0 : a.s0 + b.l0;
        ans.r0 = b.s1 ? b.r0 : b.s0 + a.r0;
        ans.m1 = max(a.l1, max(a.r1 + b.l1, b.r1));
        ans.m0 = max(a.l0, max(a.r0 + b.l0, b.r0));
        return ans;
    }
}

void check(int x, int l, int r){//调试用的 
    if(l == r){
        cout << t[x].s1 << ' ';
        return;
    }
    push_down(x);
    int mid = l + r >> 1;
    check(x * 2, l, mid);
    check(x * 2 + 1, mid + 1, r);
}

int main(){
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= n - 1; i++){
        scanf("%d", &a[i]);
    }
    build(1, 0, n - 1);
    while(m--){
        int op, l, r;
        scanf("%d%d%d", &op, &l, &r);
        if(op < 3){
            update(1, l, r, op);
        }else if(op == 3){
            int ans = query1(1, l, r);
            printf("%d\n", ans);
        }else{
            tree ans = query2(1, l, r);
            printf("%d\n", ans.m1);
        }
        //check(1, 0, n - 1);
        //cout << endl;
    }
    return 0;
}

可能没人想看 改很久了 来碰碰运气


|