【悬4关】P8765求调
  • 板块学术版
  • 楼主stripe_python
  • 当前回复2
  • 已保存回复2
  • 发布时间2025/7/2 21:03
  • 上次更新2025/7/3 15:22:26
查看原帖
【悬4关】P8765求调
928879
stripe_python楼主2025/7/2 21:03

rt,题目传送门

思路就是线段树维护区间前缀最值,照着题解看过了也没问题,交上去全屏 TLE。调不出问题来。

#include <bits/stdc++.h>
using namespace std;

#ifdef SPN_LOCAL
#define debug(x) (cerr << "On Line " << __LINE__ << ": " << #x << " = " << x << endl)
#else
#define debug(x) ((void) 0)
#endif

const int N = 1e6 + 5;

int n, q, opt, l, r;
char s[N];

struct node {
	int sum, premn, premx;
	node() : sum(0), premn(0), premx(0) {}
	node(int a, int b, int c) : sum(a), premn(b), premx(c) {}
};
node operator+ (const node& a, const node& b) {
	return node{
		a.sum + b.sum,
		min(a.premn, a.sum + b.premn),
		max(a.premx, a.sum + b.premx)
	};
}

#define ls (rt << 1)
#define rs (rt << 1 | 1)
bool rev[N << 2]; node val[N << 2];
void pushup(int rt) {val[rt] = val[ls] + val[rs];}
void reverses(int rt) {  // 取反串
	val[rt].sum = -val[rt].sum, val[rt].premx = -val[rt].premx, val[rt].premn = -val[rt].premn;
	swap(val[rt].premx, val[rt].premn), rev[rt] ^= 1;
}
void pushdown(int rt) {
	if (!rev[rt]) return;
	rev[ls] ^= 1, rev[rs] ^= 1, rev[rt] ^= 1;
	reverses(ls), reverses(rs);
}

void build(int l, int r, int rt) {
	if (l == r) {
		if (s[l] == '(') val[rt].sum = val[rt].premx = val[rt].premn = 1;
		else val[rt].sum = val[rt].premx = val[rt].premn = -1;
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, ls), build(mid + 1, r, rs), pushup(rt);
}

void reverse(int tl, int tr, int l, int r, int rt) {
	if (tl <= l && r <= tr) return reverses(rt), void();
	pushdown(rt);
	int mid = (l + r) >> 1;
	if (tl <= mid) reverse(tl, tr, l, mid, ls);
	if (tr > mid) reverse(tl, tr, mid + 1, r, rs);
	pushup(rt);
}

int query_sum(int tl, int tr, int l, int r, int rt) {
	if (tl <= l && r <= tr) return val[rt].sum;
	pushdown(rt);
	int mid = (l + r) >> 1, res = 0;
	if (tl <= mid) res += query_sum(tl, tr, l, mid, ls);
	if (tr > mid) res += query_sum(tl, tr, mid + 1, r, rs);
	return res;
}
int query_pre(int tl, int tr, int l, int r, int rt, int tot) {
	if (tl <= l && r <= tr) return val[rt].premn + tot;
	pushdown(rt);
	int mid = (l + r) >> 1, res = INT_MAX;
	if (tl <= mid) res = min(res, query_pre(tl, tr, l, mid, ls, tot)), tot += query_sum(tl, tr, l, mid, ls);
	if (tr > mid) res = min(res, query_pre(tl, tr, mid + 1, r, rs, tot));
	return res;
}

int query(int l, int r) {
	int tl = l, tr = r, res = INT_MAX;
	while (tl <= tr) {
		int mid = (tl + tr) >> 1;
		if (query_pre(l, mid, 1, n, 1, 0) >= 0) tl = mid + 1, res = mid;
		else tr = mid - 1;
	}
	if (res == INT_MAX) return 0;
	int x = res;
	while (x >= l) {
		int h = query_sum(l, x, 1, n, 1);
		if (h == 0) return x;
		x -= h;
	}
	return 0;
}

void _main() {
	cin >> n >> q >> (s + 1);
	build(1, n, 1);
	while (q--) {
		cin >> opt >> l;
		if (opt == 1) cin >> r, reverse(l, r, 1, n, 1);
		else cout << query(l, n) << '\n';
	}
} signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr), cerr.tie(nullptr);
	
	int t = 1; for (/*cin >> t*/; t--; ) _main();
	return 0;
}
2025/7/2 21:03
加载中...