30pts 求助!(玄关)
查看原帖
30pts 求助!(玄关)
807826
zjpwdyf楼主2024/10/14 21:47

神奇的 提交记录,瞪眼法 1h 无果,可能是我的线段树写得比较奇特吧,被 corner case 卡了?

下面是代码:

#include <bits/stdc++.h>
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
using namespace std;
const int N = 2e5 + 5;

struct _query {
	int x, l, r, h;
} t[N];
struct Node {
	int x, h;
} a[N];
struct node {
	int l, r, cnt;
} tr[N << 4];

bool node_cmp(Node x, Node y) {
	return x.h > y.h;
}
bool query_cmp(_query x, _query y) {
	return x.h > y.h;
}

int n, q, h, f[N], ans[N], id[N];

void build(int x, int l, int r) {
	tr[x] = {l, r, 0};
	if(l == r) {
		id[l] = x;
		return;
	}
	int m = l + r >> 1;
	build(ls(x), l, m);
	build(rs(x), m + 1, r);
}
void insert(int x) {
	f[x] = 1;
	int tx = x;
	for(x = id[x]; x; x >>= 1) {
		int st = (f[tx - 1] && tr[x].l <= tx - 1) + (f[tx + 1] && tr[x].r >= tx + 1);
		if(st == 0) tr[x].cnt++;
		if(st == 2) tr[x].cnt--;
	}
}
int query(int x, int l, int r) {
	if(r < tr[x].l || l > tr[x].r) return 0;
	if(l <= tr[x].l && r >= tr[x].r) return tr[x].cnt;
	int lc = query(ls(x), l, r), rc = query(rs(x), l, r);
	int sum = lc + rc;
	if(lc && rc && f[tr[ls(x)].r] && f[tr[rs(x)].l]) sum--;
	return sum;
}

int main() {
	cin >> n >> q;
	for(int i = 1; i <= n; i++) {
		cin >> h;
		a[i] = {i, h};
	}
	for(int i = 1; i <= q; i++) {
		cin >> t[i].l >> t[i].r >> t[i].h;
		t[i].x = i;
	}
		
	sort(a + 1, a + n + 1, node_cmp);
	sort(t + 1, t + n + 1, query_cmp);
	
	build(1, 1, n);
	for(int i = 1, j = 0; i <= q; i++) {
		while(j < n && a[j + 1].h > t[i].h) {
			j++;
			insert(a[j].x);
		}
		ans[t[i].x] = query(1, t[i].l, t[i].r);
	}
	for(int i = 1; i <= q; i++) cout << ans[i] << endl;
	return 0;
}
2024/10/14 21:47
加载中...