社区讨论

求助,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 条回复,欢迎继续交流。

正在加载回复...