动态开点线段树

#include<bits/stdc++.h>
using namespace std;
const int N = 1e7;
int n, top = 1;
struct Node{
	int lc = 0, rc = 0, s = 0;
} tr[N];
void pushup(int u){
	tr[u].s = tr[tr[u].lc].s + tr[tr[u].rc].s;
}
void change(int u, int l, int r, int x, int d){
	if(l == r){
		tr[u].s += d;
		return ;
	}
	int mid = (l+r)>>1;
	if(x <= mid){
		if(!tr[u].lc) tr[u].lc = ++top;
		change(tr[u].lc, l, mid, x, d);
	}else{
		if(!tr[u].rc) tr[u].rc = ++top;
		change(tr[u].rc, mid+1, r, x, d);
	}
	pushup(u);
}
int query(int u, int l, int r, int x, int y){
	if(l >= x && r <= y) return tr[u].s;
	int ans = 0;
	int mid = (l+r)>>1;
	if(tr[u].lc && mid >= x) ans += query(tr[u].lc, l, mid, x, y);
	if(tr[u].rc && mid+1 <= y) ans += query(tr[u].rc, mid+1, r, x, y);
	return ans;
}
int find(int u, int l, int r, int x){
	if(l == r) return l;
	int mid = (l+r)>>1;
	if(tr[u].lc && tr[tr[u].lc].s >= x) return find(tr[u].lc, l, mid, x);
	if(tr[u].lc) x -= tr[tr[u].lc].s;
	return find(tr[u].rc, mid+1, r, x);
}
int main(){
	scanf("%d", &n);
	while(n--){
		int opt, x;
		scanf("%d%d", &opt, &x);
		if(opt == 1) change(1, -1e7, 1e7, x, 1);
		else if(opt == 2) change(1, -1e7, 1e7, x, -1);
		else if(opt == 3) printf("%d\n", query(1, -1e7, 1e7, -1e7, x-1)+1);
		else if(opt == 4) printf("%d\n", find(1, -1e7, 1e7, x));
		else if(opt == 5) printf("%d\n", find(1, -1e7, 1e7, query(1, -1e7, 1e7, -1e7, x-1)));
		else if(opt == 6) printf("%d\n", find(1, -1e7, 1e7, query(1, -1e7, 1e7, -1e7, x)+1));
	}
	return 0;
}
posted @ 2026-07-20 21:17  宰杀方向盘  阅读(12)  评论(0)    收藏  举报