社区讨论
玄关求条(码风良好)
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 条回复,欢迎继续交流。
正在加载回复...