线段树上二分求调
查看原帖
线段树上二分求调
656427
iamsh楼主2025/1/20 10:29

记录 思路是先离散化,把 5、6 转化为排名的查询,但是不知道哪里错了

// Code by iamsh
#include<bits/stdc++.h>
#define lson p << 1
#define rson p << 1 | 1
#define mid (l + r >> 1)
using namespace std;
const int N = 1e5 + 5;
int n,q[N][2],tot;
map<int,int> to,bk;
struct node {
	int sum;
	node() {
		sum = 0;
	}
	node(int x) {
		sum = x;
	}
	friend node operator + (const node &l,const node &r) {
		return {l.sum + r.sum};
	}
}t[N << 2];
void add(int p,int l,int r,int x,int val) {
	if(l == r) {
		t[p].sum += val;
		return ;
	}
	if(x <= mid) {
		add(lson,l,mid,x,val);
	}
	else {
		add(rson,mid + 1,r,x,val);
	}
	t[p] = t[lson] + t[rson];
}
node query(int p,int l,int r,int ql,int qr) {
	if(l >= ql && r <= qr) {
		return t[p];
	}
	node ans;
	if(ql <= mid) {
		ans = ans + query(lson,l,mid,ql,qr);
	} 
	if(qr > mid) {
		ans = ans + query(rson,mid + 1,r,ql,qr);
	}
	return ans;
}
int rk(int p,int l,int r,int x) {
	if(l == r) {
		return bk[l];
	}
	if(t[lson].sum >= x) {
		return rk(lson,l,mid,x);
	}
	else {
		return rk(rson,mid + 1,r,x - t[lson].sum);
	}
}
void solve() {
	cin >> n; 
	for(int i = 1;i <= n;i ++) {
		cin >> q[i][0] >> q[i][1];
		to[q[i][1]];
	}
	for(auto &x : to) {
		x.second = ++ tot;
		bk[tot] = x.first;
	}
	for(int i = 1;i <= n;i ++) {
		int op = q[i][0],x = to[q[i][1]];
		if(op == 1) {
			add(1,1,tot,x,1);
		}
		else if(op == 2) {
			add(1,1,tot,x,-1);
		}
		else if(op == 3) {
			cout << query(1,1,tot,1,x - 1).sum + 1 << "\n";
		}
		else if(op == 4) {
			cout << rk(1,1,tot,x) << "\n";
		}
		else if(op == 5) {
			x = query(1,1,tot,1,x - 1).sum;
			cout << rk(1,1,tot,x) << "\n";
		}
		else {
			x = query(1,1,tot,1,x).sum + 1;
			cout << rk(1,1,tot,x) << "\n";
		}
	}

}
int main() {
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
//	ios::sync_with_stdio(0);
//	cin.tie(0),cout.tie(0);
	int t = 1;
//	cin >> t;
	while(t --) {
		solve();
	}
	return 0;
}


2025/1/20 10:29
加载中...