社区讨论

求各路大佬调代码qaq(玄 2 关)

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

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@mlntmbhg
此快照首次捕获于
2026/02/15 22:08
4 天前
此快照最后确认于
2026/02/16 17:56
3 天前
查看原帖
一大坨,但是码风良好。
CPP
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

int n, m, a[N];

struct node{
	int all0, all1, rev;
	int l1, r1, mx1, sum1;
	int l0, r0, mx0, sum0;
	int len;
	
	node(){
		all0 = all1 = rev = l1 = r1 = mx1 = sum1 = l0 = r0 = mx0 = sum0 = len = 0;
	}
} tr[N << 2];

node merge(node a, node b){
	node ans;
	ans.l1 = (a.l1 == a.len ? a.l1 + b.l1 : a.l1);
	ans.r1 = (b.r1 == b.len ? b.r1 + a.r1 : b.r1);
	ans.mx1 = max({a.mx1, b.mx1, a.r1 + b.l1});
	ans.sum1 = a.sum1 + b.sum1;
	
	ans.l0 = (a.l0 == a.len ? a.l0 + b.l0 : a.l0);
	ans.r0 = (b.r0 == b.len ? b.r0 + a.r0 : b.r0);
	ans.mx0 = max({a.mx0, b.mx0, a.r0 + b.l0});
	ans.sum0 = a.sum0 + b.sum0;
	
	ans.len = a.len + b.len;
	return ans;
}

void pushup(int now){ tr[now] = merge(tr[now << 1], tr[now << 1 | 1]); }

void push0(int now){
	tr[now].all0 = 1, tr[now].all1 = tr[now].rev = 0;
	tr[now].l1 = tr[now].r1 = tr[now].mx1 = tr[now].sum1 = 0;
	tr[now].l0 = tr[now].r0 = tr[now].mx0 = tr[now].sum0 = tr[now].len;
}

void push1(int now){
	tr[now].all1 = 1, tr[now].all0 = tr[now].rev = 0;
	tr[now].l1 = tr[now].r1 = tr[now].mx1 = tr[now].sum1 = tr[now].len;
	tr[now].l0 = tr[now].r0 = tr[now].mx0 = tr[now].sum0 = 0;
}

void pushrev(int now){
	swap(tr[now].all0, tr[now].all1);
	tr[now].rev ^= 1;
	swap(tr[now].l1, tr[now].l0);
	swap(tr[now].r1, tr[now].r0);
	swap(tr[now].mx1, tr[now].mx0);
	swap(tr[now].sum1, tr[now].sum0);
}

void pushdown(int now){
	if (tr[now].all0){
		push0(now << 1), push0(now << 1 | 1);
		tr[now].all0 = 0;
	}
	if (tr[now].all1){
		push1(now << 1), push1(now << 1 | 1);
		tr[now].all1 = 0;
	}
	if (tr[now].rev){
		pushrev(now << 1), pushrev(now << 1 | 1);
		tr[now].rev = 0;
	}
}

void build(int now, int l, int r){
	if (l == r){
		tr[now].len = 1;
		if (a[l]) tr[now].l1 = tr[now].r1 = tr[now].mx1 = tr[now].sum1 = 1;
		else tr[now].l0 = tr[now].r0 = tr[now].mx0 = tr[now].sum0 = 1;
		return ;
	}
	
	int mid = (l + r) >> 1;
	build(now << 1, l, mid);
	build(now << 1 | 1, mid + 1, r);
	pushup(now);
}

void modify(int now, int l, int r, int lt, int rt, int all0, int all1, int rev){
	if (lt <= l && r <= rt){
		if (all0) push0(now);
		if (all1) push1(now);
		if (rev) pushrev(now);
		return ;
	}
	pushdown(now);
	
	int mid = (l + r) >> 1;
	if (lt <= mid) modify(now << 1, l, mid, lt, rt, all0, all1, rev);
	if (mid < rt) modify(now << 1 | 1, mid + 1, r, lt, rt, all0, all1, rev);
	pushup(now);
}

node query(int now, int l, int r, int lt, int rt){
	if (lt <= l && r <= rt) return tr[now];
	pushdown(now);
	
	int mid = (l + r) >> 1; node ans;
	if (lt <= mid && mid < rt) ans = merge(query(now << 1, l, mid, lt, rt), query(now << 1 | 1, mid + 1, r, lt, rt));
	else if (lt <= mid) ans = query(now << 1, l, mid, lt, rt);
	else if (mid < rt) ans = query(now << 1 | 1, mid + 1, r, lt, rt);
	return ans;
}

int main(){
	cin >> n >> m;
	for (int i = 1; i <= n; i ++ ) cin >> a[i];
	build(1, 1, n);
	
	while (m -- ){
		int op, l, r; cin >> op >> l >> r; l ++, r ++;
		
		if (op == 0) modify(1, 1, n, l, r, 1, 0, 0);
		if (op == 1) modify(1, 1, n, l, r, 0, 1, 0);
		if (op == 2) modify(1, 1, n, l, r, 0, 0, 1);
		if (op == 3) cout << query(1, 1, n, l, r).sum1 << "\n";
		if (op == 4) cout << query(1, 1, n, l, r).mx1 << "\n";
	}
}

回复

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

正在加载回复...