社区讨论

玄关求条(码风良好)

P2572[SCOI2010] 序列操作参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mliubd9y
此快照首次捕获于
2026/02/12 10:29
上周
此快照最后确认于
2026/02/14 15:30
5 天前
查看原帖
只过了一个零分的附加点。
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
/*
l,r:区间左右端点。
s:区间长度。
sum1:区间内1的总数。
sum:区间最长连续1的长度。
lsum:左端点开始的最长连续1长度。
rsum:右端点结束的最长连续1长度。
tag:赋值懒标记(-1=无,0=赋值0,1=赋值1)。
rev:取反懒标记(0=无,1=有)。
*/
const int N = 2e5 + 5;
struct node {
    int l, r, s, sum1, sum, lsum, rsum, tag, rev;
}tr[N << 2];
int n, m, op, l, r, a[N];
inline void update(int p){
    tr[p].sum1 = tr[p << 1].sum1 + tr[p << 1 | 1].sum1;
    tr[p].sum = max(tr[p << 1].sum, tr[p << 1 | 1].sum);
    tr[p].sum = max(tr[p].sum, tr[p << 1].rsum + tr[p << 1 | 1].lsum);
    tr[p].lsum = tr[p << 1].lsum;
    if(tr[p << 1].lsum == tr[p << 1].s) tr[p].lsum += tr[p << 1 | 1].lsum;
    tr[p].rsum = tr[p << 1 | 1].rsum;
    if(tr[p << 1 | 1].rsum == tr[p << 1 | 1].s) tr[p].rsum += tr[p << 1].rsum;
    return ;
}
inline void downdate(int p){
    if(tr[p].tag != -1){
        tr[p << 1].tag = tr[p].tag;
        tr[p << 1].rev = 0;
        tr[p << 1].sum1 = tr[p].tag * tr[p << 1].s;
        tr[p << 1].sum = tr[p << 1].lsum = tr[p << 1].rsum = tr[p].tag * tr[p << 1].s;
        tr[p << 1 | 1].tag = tr[p].tag;
        tr[p << 1 | 1].rev = 0;
        tr[p << 1 | 1].sum1 = tr[p].tag * tr[p << 1 | 1].s;
        tr[p << 1 | 1].sum = tr[p << 1 | 1].lsum = tr[p << 1 | 1].rsum = tr[p].tag * tr[p << 1 | 1].s;
        tr[p].tag = -1;
    }
    if(tr[p].rev){
        tr[p << 1].rev ^= 1;
        tr[p << 1].sum1 = tr[p << 1].s - tr[p << 1].sum1;
        tr[p << 1].lsum = tr[p << 1].s - tr[p << 1].lsum;
        tr[p << 1].rsum = tr[p << 1].s - tr[p << 1].rsum;
        tr[p << 1].sum = tr[p << 1].s - tr[p << 1].sum;
        tr[p << 1 | 1].rev ^= 1;
        tr[p << 1 | 1].sum1 = tr[p << 1 | 1].s - tr[p << 1 | 1].sum1;
        tr[p << 1 | 1].lsum = tr[p << 1 | 1].s - tr[p << 1 | 1].lsum;
        tr[p << 1 | 1].rsum = tr[p << 1 | 1].s - tr[p << 1 | 1].rsum;
        tr[p << 1 | 1].sum = tr[p << 1 | 1].s - tr[p << 1 | 1].sum;
        tr[p].rev = 0;
    }
    return ;
}
inline void build(int p, int l, int r){
    tr[p].l = l, tr[p].r = r, tr[p].s = r - l + 1, tr[p].tag = -1, tr[p].rev = 0;
    if(l == r){
        tr[p].sum1 = tr[p].sum = tr[p].lsum = tr[p].rsum = a[l];
        return ;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    update(p);
    return ;
}
inline void change(int p, int l, int r, int val){
    if(tr[p].l >= l && tr[p].r <= r){
        tr[p].tag = val, tr[p].rev = 0;
        tr[p].sum1 = val * tr[p].s;
        tr[p].sum = tr[p].lsum = tr[p].rsum = val * tr[p].s;
        return ;
    }
    downdate(p);
    int mid = (tr[p].l + tr[p].r) >> 1;
    if(l <= mid) change(p << 1, l, r, val);
    if(r > mid) change(p << 1 | 1, l, r, val);
    update(p);
    return ;
}
inline void reverse(int p, int l, int r){
    if(tr[p].l >= l && tr[p].r <= r){
        tr[p].rev ^= 1;
        tr[p].sum1 = tr[p].s - tr[p].sum1;
        tr[p].lsum = tr[p].s - tr[p].lsum;
        tr[p].rsum = tr[p].s - tr[p].rsum;
        tr[p].sum = tr[p].s - tr[p].sum;
        return ;
    }
    downdate(p);
    int mid = (tr[p].l + tr[p].r) >> 1;
    if(l <= mid) reverse(p << 1, l, r);
    if(r > mid) reverse(p << 1 | 1, l, r);
    update(p);
    return ;
}
inline int query(int p, int l, int r){
    if(tr[p].l >= l && tr[p].r <= r) return tr[p].sum1;
    downdate(p);
    int mid = (tr[p].l + tr[p].r) >> 1;
    int res = 0;
    if(l <= mid) res += query(p << 1, l, r);
    if(r > mid) res += query(p << 1 | 1, l, r);
    return res;
}
inline node querymaxn(int p, int l, int r){
    if(tr[p].l >= l && tr[p].r <= r){
        return tr[p];
    }
    downdate(p);
    int mid = (tr[p].l + tr[p].r) >> 1;
    if(r <= mid) return querymaxn(p << 1, l, r);
    if(l > mid) return querymaxn(p << 1 | 1, l, r);
    node p1 = querymaxn(p << 1, l, r), p2 = querymaxn(p << 1 | 1, l, r);
    node res;
    res.s = p1.s + p2.s, res.sum1 = p1.sum1 + p2.sum1, res.lsum = p1.lsum;
    res.sum = max({p1.sum, p2.sum, p1.rsum + p2.lsum});
    if(p1.lsum == p1.s) res.lsum += p2.lsum;
    res.rsum = p2.rsum;
    if(p2.rsum == p2.s) res.rsum += p1.rsum;
    return res;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> a[i];
    build(1, 1, n);
    while(m--){
        cin >> op >> l >> r;
        l++, r++;
        if(!op) change(1, l, r, 0);
        else if(op == 1) change(1, l, r, 1);
        else if(op == 2) reverse(1, l, r);
        else if(op == 3) cout << query(1, l, r) << '\n';
        else cout << querymaxn(1, l, r).sum << '\n';
    }
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...