社区讨论
求助,treap36分
P3369【模板】普通平衡树参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mi7ylvdo
- 此快照首次捕获于
- 2025/11/21 05:44 4 个月前
- 此快照最后确认于
- 2025/11/21 05:44 4 个月前
CPP
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define N 100000
using namespace std;
int sum,root;
struct treap
{
int siz,rd,v,num,left,right;
}t[N+1];
void pushup(int p)
{
t[p].siz=t[t[p].left].siz+t[t[p].right].siz+t[p].num;
}
void r_right(int &p)
{
int k=t[p].left;
t[p].left=t[k].right;
t[k].right=p;
pushup(p);
pushup(k);
p=k;
}
void r_left(int &p)
{
int k=t[p].right;
t[p].right=t[k].left;
t[k].left=p;
pushup(p);
pushup(k);
p=k;
}
void insert(int &p,int x)
{
if(p==0)
{
p=++sum;
t[p].rd=rand();
t[p].num=t[p].siz=1;
t[p].v=x;
return;
}
if(t[p].v==x)
{
t[p].siz++;
t[p].num++;
return;
}
if(t[p].v>x)
{
insert(t[p].left,x);
if(t[t[p].left].rd<t[p].rd)
r_right(p);
}
else
{
insert(t[p].right,x);
if(t[t[p].right].rd<t[p].rd)
r_left(p);
}
}
void del(int &p,int x)
{
if(p==0)
return;
if(t[p].v==x)
{
if(t[p].num>1)
{
t[p].num--;
t[p].siz--;
return;
}
if(t[p].left==0||t[p].right==0)
p=t[p].left+t[p].right;
else
{
if(t[t[p].left].rd<t[t[p].right].rd)
{
r_right(p);
del(p,x);
}
else
{
r_left(p);
del(p,x);
}
}
}
else
{
if(x<t[p].v)
del(t[p].left,x);
else
del(t[p].right,x);
}
pushup(p);
}
int rank(int x)
{
int p=root,res=0;
while(p!=0)
{
if(x==t[p].v)
return res+t[t[p].left].siz+1;
if(x<t[p].v)
p=t[p].left;
else
{
res+=t[t[p].left].siz+t[p].num;
p=t[p].right;
}
}
return res;
}
int query_pre(int x)
{
int p=root,res=0;
while(p!=0)
{
if(t[p].v<=x)
{
res=t[p].v;
p=t[p].right;
}
else
p=t[p].left;
}
return res;
}
int query_suf(int x)
{
int p=root,res=0;
while(p!=0)
{
if(t[p].v>=x)
{
res=t[p].v;
p=t[p].left;
}
else
p=t[p].right;
}
return res;
}
int query_kth(int k)
{
int p=root;
while(p!=0)
{
// printf("%d\n",t[p].v);
if(t[t[p].left].siz<k&&t[t[p].left].siz+t[p].num>=k)
return t[p].v;
if(t[t[p].left].siz>=k)
p=t[p].left;
else
{
k-=t[t[p].left].siz+t[p].num;
p=t[p].right;
}
}
return 0;
}
void print(int p)
{
if(p==0)
return;
print(t[p].left);
for(int i=1;i<=t[p].num;i++)
printf("%d ",t[p].v);
print(t[p].right);
}
int main()
{
srand(time(0));
int n;
scanf("%d",&n);
while(n--)
{
int tq,x;
scanf("%d %d",&tq,&x);
if(tq==1)
insert(root,x);
if(tq==2)
del(root,x);
if(tq==3)
printf("%d\n",rank(x));
if(tq==4)
printf("%d\n",query_kth(x));
if(tq==5)
printf("%d\n",query_pre(x));
if(tq==6)
printf("%d\n",query_suf(x));
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...