线段树套fhq-treap求助,悬关
查看原帖
线段树套fhq-treap求助,悬关
716260
SegmentTree_楼主2024/1/11 00:35

样例都过不去

#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 trnode{
	int ls, rs;
	int key, pri, siz;
}treap[N << 6];
int tsiz;
void update(int rt){
	treap[rt].siz = treap[treap[rt].ls].siz + treap[treap[rt].rs].siz + 1;
}
void newnode(int x){
	++tsiz;
	treap[tsiz].siz = 1;
	treap[tsiz].ls = treap[tsiz].rs = 0;
	treap[tsiz].key = x;
	treap[tsiz].pri = rand();
}
void split(int rt, int x, int &l, int &r){
	if (rt == 0){
		l = r = 0;
		return;
	}
	if (treap[rt].key <= x) l = rt, split(treap[rt].rs, x, treap[rt].rs, r);
	else r = rt, split(treap[rt].ls, x, l, treap[rt].ls);
	update(rt);
}
int merge(int l, int r){
	if (l == 0 || r == 0) return l + r;
	if (treap[l].pri > treap[r].pri){
		treap[l].rs = merge(treap[l].rs, r);
		update(l);
		return l;
	}
	else{
		treap[r].ls = merge(l, treap[r].ls);
		update(r);
		return r;
	}
}
int insert(int &root, int x){
	int l, r;
	split(root, x, l, r);
	newnode(x);
	root = merge(merge(l, tsiz), r);
	return tsiz;
}
void del(int &root, int x){
	int l, m, r;
	split(root, x, l, r);
	split(l, x - 1, l, m);
	m = merge(treap[m].ls, treap[m].rs);
	root = merge(merge(l, m), r);
}
int rnk(int &root, int x){
	int l, r, res;
	split(root, x - 1, l, r);
	res = treap[l].siz + 1;
	root = merge(l, r);
	return res;
}
int gkth(int rt, int k){
	if (k == treap[treap[rt].ls].siz + 1) return rt;
	if (k <= treap[treap[rt].ls].siz) return gkth(treap[rt].ls, k);
	return gkth(treap[rt].rs, k - treap[treap[rt].ls].siz - 1);
}
int kth(int rt, int k){
	return treap[gkth(rt, k)].key;
}
int kth1(int rt, int k){
	return kth(rt, tsiz - k + 1);
}
int pre(int &root, int x){
	int l, r, res;
	split(root, x - 1, l, r);
	res = kth(l, treap[l].siz);
	root = merge(l, r);
	return res;
}	
int suc(int &root, int x){
	int l, r, res;
	split(root, x, l, r);
	res = kth(r, 1);
	root = merge(l, r);
	return res;
}
struct node{
	int l, r;
}tr[N << 2];
int root[N << 2], a[N], n, q;
void build (int id, int l, int r){
	tr[id].l = l;
	tr[id].r = r;
	for (int i = l;i <= r;i++) insert(root[id], a[i]);
	if (l == r) return;
	int mid = (l + r) >> 1;
	build(lid, l, mid);
	build(rid, mid + 1, r);
}
int qrank(int id, int l, int r, int x){
	if (tr[id].r < l || tr[id].l > r) return 0;
	if (l <= tr[id].l && tr[id].r <= r) return rnk(root[id], x) - 1;
	return qrank(lid, l, r, x) + qrank(rid, l, r, x);
}
int qkth(int l, int r, int rk){
	int x = 0, y = 1e8, res = -1;
	while (x <= y){
		int mid = (x + y) >> 1;
		if (qrank(1, l, r, mid) + 1 <= rk){
			res = mid;
			x = mid + 1;
		}
		else y = mid - 1;
	}
	return res;
}
void update(int id, int pos, int k){
	del(root[id], a[pos]);
	insert(root[id], k);
	if (tr[id].l == tr[id].r) return;
	int mid = (tr[id].l + tr[id].r) >> 1;
	if (pos <= mid) update(lid, pos, k);
	else update(rid, pos, k);
}
int qpre(int id, int l, int r, int k){
	if (tr[id].r < l || tr[id].l > r) return -2147483647;
	if (l <= tr[id].l && tr[id].r <= r){
		return pre(root[id], k);
	}
	return max(qpre(lid, l, r, k), qpre(rid, l, r, k));
}
int qsuc(int id, int l, int r, int k){
	if (tr[id].r < l || tr[id].l > r) return 2147483647;
	if (l <= tr[id].l && tr[id].r <= r) return suc(root[id], k);
	return min(qsuc(lid, l, r, k), qsuc(rid, l, r, k));
}
int main(){
	srand(time(NULL));
	cin >> n >> q;
	for (int i = 1;i <= n;i++){
		cin >> a[i];
	}
	while (q--){
		int op, pos, l, r, k;
		cin >> op;
		if (op == 3){
			cin >> pos >> k;
			update(1, pos, k);
			a[pos] = k;
		}
		else{
			cin >> l >> r >> k;
			if (op == 1){
				cout << qrank(1, l, r, k) << '\n';
			}
			else if (op == 2){
				cout << qkth(l, r, k) << '\n';
			}
			else if (op == 4){
				cout << qpre(1, l, r, k) << '\n';
			}
			else if (op == 5){
				cout << qsuc(1, l, r, k) << '\n';
			}
		}
	}
	return 0;
}
2024/1/11 00:35
加载中...