社区讨论

线段树30pts求助

P4344[SHOI2015] 脑洞治疗仪参与者 2已保存回复 5

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@lo26wcq2
此快照首次捕获于
2023/10/23 08:59
2 年前
此快照最后确认于
2023/11/03 09:14
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;

#define int long long
const int mod = 998244353;
const int maxn = 2e5 + 10;

struct node{
	int l, r, sum, mx, lmx, rmx, tag;
}tree[maxn*4];

int n, Q, x, y, z, p, op;

void push_up(int i){
	tree[i].sum = tree[i*2].sum + tree[i*2+1].sum;
	tree[i].mx = max(tree[i*2].rmx + tree[i*2+1].lmx, max(tree[i*2].mx, tree[i*2+1].mx));
	if(tree[i*2].mx == tree[i*2].r - tree[i*2].l + 1) tree[i].lmx = tree[i*2].mx + tree[i*2+1].lmx;
	else tree[i].lmx = tree[i*2].lmx;
	if(tree[i*2+1].mx == tree[i*2+1].r - tree[i*2+1].l + 1) tree[i].rmx = tree[i*2+1].mx + tree[i*2].rmx;
	else tree[i].rmx = tree[i*2+1].rmx;
}

void build(int i, int l, int r){
	tree[i].l = l, tree[i].r = r, tree[i].tag = -1;
	if(l == r){
		tree[i].sum = 1;
		return;
	}
	int mid = l + r >> 1;
	build(i * 2, l, mid);
	build(i * 2 + 1, mid + 1, r);
	push_up(i);
}

void push_down(int i){
	if(tree[i].tag != -1){
		if(tree[i].tag){
			tree[i*2].sum = tree[i*2].r - tree[i*2].l + 1;
			tree[i*2].lmx = tree[i*2].rmx = tree[i*2].mx = 0;
			tree[i*2+1].sum = tree[i*2+1].r - tree[i*2+1].l + 1;
			tree[i*2+1].lmx = tree[i*2+1].rmx = tree[i*2+1].mx = 0;
		}
		else{
			tree[i*2].sum = 0;
			tree[i*2].lmx = tree[i*2].rmx = tree[i*2].mx = tree[i*2].r - tree[i*2].l + 1;
			tree[i*2+1].sum = 0;
			tree[i*2+1].lmx = tree[i*2+1].rmx = tree[i*2+1].mx = tree[i*2+1].r - tree[i*2+1].l + 1;
		}
		tree[i*2].tag = tree[i*2+1].tag = tree[i].tag;
		tree[i].tag = -1;
	}
}

void update(int i, int x, int y, int z){
	int l = tree[i].l, r = tree[i].r;
	if(x <= l && r <= y){
		if(z){
			tree[i].sum = r - l + 1;
			tree[i].lmx = tree[i].rmx = tree[i].mx = 0;
		}
		else{
			tree[i].sum = 0;
			tree[i].lmx = tree[i].rmx = tree[i].mx = r - l + 1;
		}
		tree[i].tag = z;
		return;
	}
	push_down(i);
	int mid = l + r >> 1;
	if(mid >= x) update(i * 2, x, y, z);
	if(mid < y) update(i * 2 + 1, x, y, z);
	push_up(i);
}

node query(int i, int x, int y){
	int l = tree[i].l, r = tree[i].r;
	if(x <= l && r <= y) return tree[i];
	push_down(i);
	int mid = l + r >> 1;
	if(mid >= y) return query(i * 2, x, y);
	if(mid < x) return query(i * 2 + 1, x, y);
	node L = query(i * 2, x, y), R = query(i * 2 + 1, x, y), res;
	res.sum = L.sum + R.sum;
	res.mx = max(L.rmx + R.lmx, max(L.mx, R.mx));
	if(L.lmx == L.r - L.l + 1) res.lmx = L.lmx + R.lmx;
	else res.lmx = L.lmx;
	if(R.rmx == R.r - L.l + 1) res.rmx = R.rmx + L.rmx;
	else res.rmx = R.rmx;
	return res;
}

void change(int l0, int r0, int l1, int r1){
	int num = query(1, l0, r0).sum;
	if(!num) return;
	update(1, l0, r0, 0);	
	int l = l1, r = r1;
	while(l < r){
		int mid = l + r + 1 >> 1;
		if(mid - l1 + 1 - query(1, l1, mid).sum <= num) l = mid;
		else r = mid - 1;
	}
	update(1, l1, l, 1);
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n >> Q;
	build(1, 1, n);
	while(Q--){
		cin >> op;
		if(op == 0){
			cin >> x >> y;
			update(1, x, y, 0);
		}
		else if(op == 1){
			cin >> x >> y >> z >> p;
			change(x, y, z, p);
		}
		else{
			cin >> x >> y;
			cout << query(1, x, y).mx << endl;
		}
	}
	return 0;
}

回复

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

正在加载回复...