救救孩子吧,只有 10分
查看原帖
救救孩子吧,只有 10分
158846
xixike楼主2021/11/11 20:52

rt

#include <bits/stdc++.h>
#define ls rt << 1
#define rs rt << 1 | 1

using namespace std;

inline int read(){
    int x = 0;
    char ch = getchar();
    while(!isdigit(ch)) ch = getchar();
    while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x;
}

const int N = 1e5 + 10;
int n, m;
int a[N];
struct Seg_tree{
    int sum, len, maxl0, maxr0, maxzd0, maxl1, maxr1, maxzd1, cov, rev;
    void Swap(){
        swap(maxl0, maxl1), swap(maxr0, maxr1), swap(maxzd0, maxzd1);
        sum = len - sum;
    }
}t[N << 2];

inline void pushup(int rt){
    // cout << "ppushup" << endl;
    // t[rt].len = t[ls].len + t[rs].len;
    t[rt].sum = t[ls].sum + t[rs].sum;

    t[rt].maxl1 = t[ls].maxl1;
    t[rt].maxr1 = t[rs].maxr1;
    if(t[ls].maxl1 == t[ls].len) t[rt].maxl1 = t[ls].len + t[rs].maxl1;
    if(t[rs].maxr1 == t[rs].len) t[rt].maxr1 = t[rs].len + t[ls].maxr1;
    t[rt].maxzd1 = max(t[ls].maxr1 + t[rs].maxl1, max(t[ls].maxzd1, t[rs].maxzd1));

    t[rt].maxl0 = t[ls].maxl0;
    t[rt].maxr0 = t[rs].maxr0;
    if(t[ls].maxl0 == t[ls].len) t[rt].maxl0 = t[ls].len + t[rs].maxl0;
    if(t[rs].maxr0 == t[rs].len) t[rt].maxr0 = t[rs].len + t[ls].maxr0;
    t[rt].maxzd0 = max(t[ls].maxr0 + t[rs].maxl0, max(t[ls].maxzd0, t[rs].maxzd0));
}

inline void pushdown(int rt){
    if(t[rt].cov != -1){
        // cout << "pushdown    " << rt << "  " << t[rt].cov << endl;
        t[ls].maxl1 = t[ls].maxr1 = t[ls].maxzd1 = t[ls].sum = t[ls].len * t[rt].cov;
        t[rs].maxl1 = t[rs].maxr1 = t[rs].maxzd1 = t[rs].sum = t[rs].len * t[rt].cov;
        t[ls].maxl0 = t[ls].maxr0 = t[ls].maxzd0 = t[ls].len * (t[rt].cov ^ 1);
        t[rs].maxl0 = t[rs].maxr0 = t[rs].maxzd0 = t[rs].len * (t[rt].cov ^ 1);
        // cout << t[rt].sum << " " << t[ls].sum << " " << t[rs].sum << endl;
        t[ls].cov = t[rs].cov = t[rt].cov;
        t[ls].rev = t[rs].rev = 0;
        t[rt].cov = -1;
    }
    if(t[rt].rev){
        // cout << "pushdown  " << endl;
        t[ls].Swap(), t[rs].Swap();
        t[ls].rev ^= 1, t[rs].rev ^= 1;
        t[rt].rev = 0;
    }
}

inline void build(int l, int r, int rt){
    t[rt].cov = -1, t[rt].len = r - l + 1;
    if(l == r){
        t[rt].maxl1 = t[rt].maxr1 = t[rt].maxzd1 = t[rt].sum = a[l];
        t[rt].maxl0 = t[rt].maxr0 = t[rt].maxzd0 = a[l] ^ 1;
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, ls);
    build(mid + 1, r, rs);
    pushup(rt);
}

inline void update_cov(int L, int R, int k, int l, int r, int rt){
    if(L <= l && r <= R){
        // cout << "cover  " << rt << endl;
        t[rt].maxl1 = t[rt].maxr1 = t[rt].maxzd1 = t[rt].sum = t[rt].len * k;
        t[rt].maxl0 = t[rt].maxr0 = t[rt].maxzd0 = t[rt].len * (k ^ 1);
        t[rt].cov = k;
        return;
    }
    pushdown(rt);
    int mid = (l + r) >> 1;
    if(L <= mid) update_cov(L, R, k, l, mid, ls);
    if(R > mid) update_cov(L, R, k, mid + 1, r, rs);
    pushup(rt);
}

inline void update_rev(int L, int R, int l, int r, int rt){
    if(L <= l && r <= R){
        // cout << t[rt].sum << endl;
        // cout << "rttt  " << rt << " " << l << " " << r << " " << t[rt].maxzd1 << endl;
        t[rt].Swap();
        t[rt].rev ^= 1;
        // cout << t[rt].maxzd1 << endl;
        return;
    }
    pushdown(rt);
    // cout << rt << "  " << l << " " << r << "   maxzd1   ";
    // for(int i = 1; i <= (n << 2); ++i)
    //     cout << t[i].maxzd1 << " ";
    // cout << endl;
    int mid = (l + r) >> 1;
    if(L <= mid) update_rev(L, R, l, mid, ls);
    if(R > mid) update_rev(L, R, mid + 1, r, rs);
    pushup(rt);
}

inline int query_sum(int L, int R, int l, int r, int rt){
    if(L <= l && r <= R) return t[rt].sum;
    pushdown(rt);
    int mid = (l + r) >> 1, res = 0;
    if(L <= mid) res += query_sum(L, R, l, mid, ls);
    if(R > mid) res += query_sum(L, R, mid + 1, r, rs);
    return res;
}

inline int query_len(int L, int R, int l, int r, int rt){
    if(L <= l && r <= R) return t[rt].maxzd1;
    pushdown(rt);
    int mid = (l + r) >> 1, res = min(t[ls].maxr1, mid - L + 1) + min(t[rs].maxl1, R - mid);
    if(L <= mid) res = max(res, query_len(L, R, l, mid, ls));
    if(R > mid) res = max(res, query_len(L, R, mid + 1, r, rs));
    return res;
}

int main(){
    freopen("P2572.in", "r", stdin);
    freopen("P2572.out", "w", stdout);
    n = read(), m = read();
    for(int i = 1; i <= n; ++i)
        a[i] = read();
    build(1, n, 1);
    // for(int i = 1; i <= (n << 2); ++i)
    //     cout << t[i].sum << " ";
    // cout << endl;
    // printf("%d   %d\n", query_sum(1, 5, 1, n, 1), query_len(5, 9, 1, n, 1));
    for(int i = 1; i <= m; ++i){
        int op = read(), l = read() + 1, r = read() + 1;
        if(!op) update_cov(l, r, 0, 1, n, 1);
        else if(op == 1) update_cov(l, r, 1, 1, n, 1);
        else if(op == 2) update_rev(l, r, 1, n, 1);
        else if(op == 3) printf("%d\n", query_sum(l, r, 1, n, 1));
        else printf("%d\n", query_len(l, r, 1, n, 1));
        // cout << "i " << i << endl;
        // for(int j = 1; j <= (n << 2); ++j)
        //     cout << t[j].maxzd1 << " ";
        // cout << endl << endl << endl;
    }
    return 0;
}
2021/11/11 20:52
加载中...