求助线段树套treap
查看原帖
求助线段树套treap
716260
SegmentTree_楼主2024/1/8 11:51

操作三炸了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lid (id << 1)
#define rid (id << 1 | 1)
const int N = 5e4+5;
struct treap_node{
	int ls, rs;
	int key, pri, size;
};
struct Treap{
	const double alpha = 0.75;
	treap_node t[N];
	int cnt;
	void newnode(int x){
		++cnt;
		t[cnt].size = 1;
		t[cnt].ls = t[cnt].rs = 0;
		t[cnt].key = x;
		t[cnt].pri = rand();
	}
	void update(int u){
		t[u].size = t[t[u].ls].size + t[t[u].rs].size + 1;
	}
	void rotate(int &o, int d){ //d=0 right d=1 left
		int k;
		if (d == 1){
			k = t[o].rs;
			t[o].rs = t[k].ls;
			t[k].ls = o;
		}
		else{
			k = t[o].ls;
			t[o].ls = t[k].rs;
			t[k].rs = o;
		}
		t[k].size = t[o].size;
		update(o);
		o = k;
	}
	void insert(int &u, int x){
		if (u == 0){
			newnode(x);
			u = cnt;
			return;
		}
		++t[u].size;
		if (x >= t[u].key) insert(t[u].rs, x);
		else insert(t[u].ls, x);
		if (t[u].ls != 0 && t[u].pri > t[t[u].ls].pri) rotate(u, 0);
		if (t[u].rs != 0 && t[u].pri >t[t[u].rs].pri) rotate(u, 1);
		update(u);
	}
	void del(int &u, int x){
		--t[u].size;
		if (t[u].key == x){
			if(t[u].ls==0 && t[u].rs == 0){
				u = 0;
				return;
			}
			if(t[u].ls == 0 || t[u].rs == 0){
				u = t[u].ls + t[u].rs;
				return;
			}
			if (t[t[u].ls].pri < t[t[u].rs].pri){
				rotate(u, 0);
				del(t[u].rs, x);
				return;
			}
			else{
				rotate(u, 1);
				del(t[u].ls, x);
				return;
			}
		}
		if(t[u].key >= x) del(t[u].ls, x);
		else del(t[u].rs, x);
		update(u);
	}
	int rnk(int u, int x){
		if (u == 0) return 0;
		if (x > t[u].key) return t[t[u].ls].size + 1 + rnk(t[u].rs, x);
		return rnk(t[u].ls, x);
	}
	int kth(int u, int k){
		if (k == t[t[u].ls].size + 1) return t[u].key;
		if (k > t[t[u].ls].size + 1) return kth(t[u].rs, k - t[t[u].ls].size - 1);
		if (k <= t[t[u].ls].size) return kth(t[u].ls, k);
	}
	int pre(int u, int x){
		if (u == 0) return 0;
		if (t[u].key >= x) return pre(t[u].ls, x);
		int tmp = pre(t[u].rs, x);
		if (tmp == 0) return t[u].key;
		return tmp;
	}
	int suc(int u, int x){
		if (u == 0) return 0;
		if (t[u].key <= x) return suc(t[u].rs, x);
		int tmp = suc(t[u].ls, x);
		if (tmp == 0) return t[u].key;
		return tmp;
	}
}treap;
struct node{
	int l, r;
	int root;
}tr[N << 2];
int a[N];
void build(int id, int l, int r){
	tr[id].l = l;
	tr[id].r = r;
	for (int i = l;i <= r;i++) treap.insert(tr[id].root, a[i]);
	if (l == r) return;
	int mid = (l + r) >> 1;
	build(lid, l, mid);
	build(rid, mid + 1, r);
}
void modify(int id, int x, int y){
	treap.del(tr[id].root, a[x]);
	treap.insert(tr[id].root, y);
	if (tr[id].l == tr[id].r) return;
	int mid = (tr[id].l + tr[id].r) >> 1;
	if (x <= mid) modify(lid, x, y);
	else modify(rid, x, y);
}
int qrank(int id, int l, int r, int k){
	if (tr[id].l > r || tr[id].r < l) return 0;
	if (l <= tr[id].l && tr[id].r <= r) return treap.rnk(tr[id].root, k);
	return qrank(lid, l, r, k) + qrank(rid, l, r, k);
}
int qkth(int a, int b, int k){
	int l = 0, r = 1e8;
	while (l < r){
		int mid = (l + r) >> 1;
		if (qrank(1, a, b, mid) < k) l = mid;
		else r = mid - 1;
	}
	return r;
}
int qpre(int id, int l, int r, int k){
	if (tr[id].l > r || tr[id].r < l) return -2147483647;
	if (l <= tr[id].l && tr[id].r <= r) return treap.pre(tr[id].root, k);
	return max(qpre(lid, l, r, k), qpre(rid, l, r, k));
}
int qsuf(int id, int l, int r, int k){
	if (tr[id].l > r || tr[id].r < l) return 2147483647;
	if (l <= tr[id].l && tr[id].r <= r) return treap.suc(tr[id].root, k);
	return min(qsuf(lid, l, r, k), qsuf(rid, l, r, k));
}
int n, q;
int main(){
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> q;
	for (int i = 1;i <= n;i++) cin >> a[i];
	while (q--){
		int op;
		cin >> op;
		if (op == 1){
			int l, r, k;
			cin >> l >> r >> k;
			cout << qrank(1, l, r, k) + 1 << '\n';
		}
		else if (op == 2){
			int l, r, k;
			cin >> l >> r >> k;
			cout << qkth(l, r, k) << '\n';
		}
		else if (op == 3){
			int pos, k;
			cin >> pos >> k;
			modify(1, pos, k);
		}
		else if (op == 4){
			int l, r, k;
			cin >> l >> r >> k;
			cout << qpre(1, l, r, k) << '\n';
		}
		else{
			int l, r, k;
			cin >> l >> r >> k;
			cout << qsuf(1, l, r, k) << '\n';
		}
	}
	return 0;
}  
2024/1/8 11:51
加载中...