mxqz 线段树
查看原帖
mxqz 线段树
526017
COsm0s楼主2023/7/21 12:38
#include<bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;

struct question {
	int l, r, opt;
} q[N];

struct Seg_tree {
	int sum, add;
} tree[N << 2];

int n, m, aim;

int b[N], a[N];

inline void PushUp(int x) {
	tree[x].sum = tree[x << 1].sum + tree[x << 1 | 1].sum; 
}

void Build(int l, int r, int x) {
	
	if(l == r) {
		
		tree[x].sum = b[l];
		
		return ;
	}
	
	int mid = l + r >> 1;
	
	Build(l, mid, x << 1);
	
	Build(mid + 1, r, x << 1 | 1);
	
	PushUp(x);
}

inline void modify(int x, int l, int r, int num) {
	
	tree[x].sum = (r - l + 1) * num;
			
	tree[x].add = num;
	
	return ;
}

inline void PushDown(int x, int l, int r) {
	
	if(~tree[x].add) {
		
		int mid = l + r >> 1;
		
		modify(x << 1, l, mid, tree[x].add);
		
		modify(x << 1 | 1, mid + 1, r, tree[x].add);
	
		tree[x].add = -1;
	}
}	

void UpDate(int L, int R, int l, int r, int x, int num) {
	
	if(L <= l && r <= R) {
		
		modify(x, l, r, num);
	
		return ;
	}
	
	int mid = l + r >> 1;
	
	PushDown(x, l, r);
	
	if(L <= mid) UpDate(L, R, l, mid, x << 1, num);
	
	if(mid < R) UpDate(L, R, mid + 1, r, x << 1 | 1, num);
	
	PushUp(x);
}

int Query(int L, int R, int l, int r, int x) {
	
	if(L <= l && r <= R) return tree[x].sum;
	
	PushDown(x, l, r);
	
	int mid = l + r >> 1, ans = 0;
	
	if(L <= mid) ans += Query(L, R, l, mid, x << 1);
	
	if(mid < R) ans += Query(L, R, mid + 1, r, x << 1 | 1);
	
	return ans;
}

bool check(int mid) {
			
	for(int i = 0; i < (N << 2); i ++) tree[i].sum = 0, tree[i].add = -1;	
		
	for(int i = 1; i <= n; i ++) 
		b[i] = (a[i] >= mid);
	
	Build(1, n, 1);
	
	for(int i = 1; i <= m; i ++) {
		
		int cnt = Query(q[i].l, q[i].r, 1, n, 1);
		
		if(!q[i].opt) {
			
			UpDate(q[i].r - cnt + 1, q[i].r, 1, n, 1, 1);
			
			UpDate(q[i].l, q[i].r - cnt, 1, n, 1, 0);
		}
		
		else {
			
			UpDate(q[i].l, q[i].l + cnt - 1, 1, n, 1, 1);
			
			UpDate(q[i].l + cnt, q[i].r, 1, n, 1, 0);
		}
	}
	
	return Query(aim, aim, 1, n, 1);
}

int Middle() {
	
	cin >> aim;
	
	int l = 1, r = n, ans = 0;
	
	while(l <= r) {
		
		int mid = l + r >> 1;
		
		if(check(mid)) l = mid + 1, ans = mid;
		
		else r = mid - 1;
		
	} 
	
	return ans;
}
signed main() {

	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);

	cin >> n >> m;

	for (int i = 1; i <= n; i ++) cin >> a[i];

	for (int i = 1; i <= m; i ++) {
		cin >> q[i].opt >> q[i].l >> q[i].r;
	}

	cout << Middle() << '\n';
	
	return 0;
}

RE 4 个点,60 pts。

求解答。

2023/7/21 12:38
加载中...