社区讨论

treap MLE爆30,求调

P3369【模板】普通平衡树参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mdofjzly
此快照首次捕获于
2025/07/29 19:04
7 个月前
此快照最后确认于
2025/07/29 21:09
7 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
struct FastMod{
	using ull=unsigned long long;
    using L=__int128;
    ull b,m;
    FastMod(ull b):b(b),m(ull((L(1)<<64)/b)){}
    ull reduce(ull a)
	{
        ull q=(ull)((L(m)*a)>>64),r=a-q*b;
        return r>=b?r-b:r;
    }
}F(330);
inline long long read(){
	long long s=0,k=1;
	char c=getchar();
	while(c>'9'||c<'0'){
		if(c=='-') k=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		s=(s<<3)+(s<<1)+(c^48);
		c=getchar();
	}
	return s*k;
}
const int N=2e5+55,mod=998244353;
int cnt,root,n,opt,cv;
struct treap{
	int data,val,l,r,sz;
}t[N];
void up(int p){t[p].sz=t[t[p].l].sz+t[t[p].r].sz+1;} 
void right_rorate(int &p){
	int tmp=t[p].l;
	t[p].l=t[tmp].r;
	t[tmp].r=p;
	t[tmp].sz=t[p].sz;
	up(p);
	p=tmp;
}
void left_rorate(int &p){
	int tmp=t[p].r;
	t[p].r=t[tmp].l;
	t[tmp].l=p;
	t[tmp].sz=t[p].sz;
	up(p);
	p=tmp;
}
void insert(int &now,int data){
	if(now==0){
		now=++cnt;
		t[now].sz=1;
		t[now].data=data;
		t[now].val=F.reduce(rand()*rand());
		return;
	}
	t[now].sz++;
	if(data>=t[now].data) insert(t[now].r,data);
	else insert(t[now].l,data);
	if(t[now].l!=0 && t[now].val>t[t[now].l].val) right_rorate(now);
	if(t[now].r!=0 && t[now].val>t[t[now].r].val) left_rorate(now);
	up(now);
}
void erase(int &now,int data){
	t[now].sz--;
	if(t[now].data==data){
		if(t[now].l==0 && t[now].r==0){
			now=0;
			return;
		}
		if(t[now].l==0||t[now].r==0) now=t[now].l+t[now].r;
		if(t[t[now].l].val<t[t[now].r].val){
			right_rorate(now);
			erase(t[now].r,data);
		}
		else{
			left_rorate(now);
			erase(t[now].l,data);
			return;
		}
	}
	if(t[now].data>=data) erase(t[now].l,data);
	else erase(t[now].r,data);
	up(now);
}
int _rank(int now,int data){
	if(now==0) return 0;
	if(data>t[now].data) return t[t[now].l].sz+1+_rank(t[now].r,data);
	return _rank(t[now].l,data);
}
int find(int now,int rank){
	if(rank==t[t[now].l].sz+1) return t[now].data;
	if(rank>t[t[now].l].sz+1) return find(t[now].r,rank-t[t[now].l].sz-1);
	return find(t[now].l,rank);
}
int pre(int now,int data){
	if(now==0) return 0;
	if(t[now].data>=data) return pre(t[now].l,data);
	int tmp=pre(t[now].r,data);
	if(tmp==0) return t[now].data;
	return tmp;
}
int suf(int now,int data){
	if(now==0) return 0;
	if(t[now].data<=data) return pre(t[now].r,data);
	int tmp=suf(t[now].l,data);
	if(tmp==0) return t[now].data;
	return tmp;
}
signed main(){
	F = FastMod(19620817);
	srand(19620817);
	n=read();
	while(n--){
		opt=read();cv=read();
		if(opt==1) insert(root,cv);
		if(opt==2) erase(root,cv);
		if(opt==3) printf("%d\n",_rank(root,cv)+1);
		if(opt==4) printf("%d\n",find(root,cv));
		if(opt==5) printf("%d\n",pre(root,cv));
		if(opt==6) printf("%d\n",suf(root,cv));
	}
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...