Treap求调,样例也没过
查看原帖
Treap求调,样例也没过
343246
迷失的星辰楼主2023/11/5 10:30

前言:

样例没有过,输出结果为

-2147483647
644985
-2147483647

不过第一个点A了(?)

Code:

#include <bits/stdc++.h>
using namespace std;
int n,opt,x;
struct Treap_Node
{
    int ls,rs;    //左子树下标、右子树下标 
    int k,w;      //下标、权值 
    int cnt;      //元素重复次数 
    int size;     //子树大小 
} Treap[100005];
int root,Treap_size;

int New(int val)
{
    Treap_size++;
    Treap[Treap_size].k=val;
    Treap[Treap_size].w=rand();
    Treap[Treap_size].cnt=Treap[Treap_size].size=1;
    return Treap_size;
}

void update(int rt)
{
    Treap[rt].size=Treap[Treap[rt].ls].size+Treap[Treap[rt].rs].size+Treap[rt].cnt;
}                                                                //.size改为了.cnt 

void build()
{
    
    
    root=New(-INT_MAX);
    Treap[1].rs=New(INT_MAX);;
    update(root);
}
void lrotate(int &rt)
{
    int rs=Treap[rt].rs;
    Treap[rt].rs=Treap[rs].ls;
    Treap[rs].ls=rt;
    rt=rs;
    update(Treap[rt].ls);
    update(rt);
}

void rrotate(int &rt)
{
    int ls=Treap[rt].ls;
    Treap[rt].ls=Treap[ls].rs;
    Treap[ls].rs=rt;
    rt=ls;
    update(Treap[rt].rs);
    update(rt);
}

void insert(int &rt,int val)
{
    if (rt==0)
    {
        rt=New(val);
        return;
    }
    if (Treap[rt].k==val)
    {
        Treap[rt].cnt++;
        //update(rt);
        //return;
    }
    /*if (Treap[rt].k>val)
    {
        insert(Treap[rt].ls,val);
        if (Treap[rt].w<Treap[Treap[rt].ls].w)   //
            rrotate(rt);
    }*/ 
    else
    {
        /*insert(Treap[rt].rs,val);
        if (Treap[rt].w<Treap[Treap[rt].rs].w)  //
            lrotate(rt);*/
		if (Treap[rt].k<val)
		{
			insert(Treap[rt].ls,val);
			if (Treap[rt].w<Treap[Treap[rt].ls].w)
			{
				rrotate(rt);
			}
		}
		else
		{
			insert(Treap[rt].rs,val);
			if (Treap[rt].w<Treap[Treap[rt].rs].w)
			{
				lrotate(rt);
			}
		}
    }
    update(rt);
    return;
}

void del(int &rt,int val)
{
    if (rt==0) return;
    if (Treap[rt].k==val)
    {
        if (Treap[rt].cnt>1)
        {
            Treap[rt].cnt--;
            update(rt);
            return;
        }
        if (Treap[rt].ls || Treap[rt].rs)
        {
            
            /*else*/ if (Treap[rt].rs==0 || Treap[Treap[rt].ls].cnt>Treap[Treap[rt].rs].cnt)
            {
                rrotate(rt);
                del(Treap[rt].rs,val);
            }
			//if (Treap[rt].ls==0 || Treap[Treap[rt].ls].w>Treap[Treap[rt].rs].w)
            else
			{
                lrotate(rt);
                del(Treap[rt].ls,val);
            }
        }
        else rt=0;
        return;
    }
    if (Treap[rt].k>val) del(Treap[rt].ls,val);
    else del(Treap[rt].rs,val);
    update(rt);
}

int getrank(int rt,int val)
{
    if (rt==0) return 0;
    if (Treap[rt].k==val) return Treap[Treap[rt].ls].size+1;
    else if (Treap[rt].k>val) return getrank(Treap[rt].ls,val);
    else return getrank(Treap[rt].rs,val)+Treap[Treap[rt].ls].size+Treap[rt].cnt;
    //else if (Treap[rt].k<val) return getrank(Treap[rt].rs,val);
}   //由h:140修改为h:139 

int getranx(int rt,int ranx)
{
    if (rt==0) return INT_MAX;
    if (Treap[Treap[rt].ls].size>=ranx)
        return getranx(Treap[rt].ls,ranx);
    else if (Treap[Treap[rt].ls].size+Treap[rt].cnt>=ranx)
        return Treap[rt].k;
    else return getranx(Treap[rt].rs,ranx-Treap[Treap[rt].ls].size-Treap[rt].cnt);
}

int getpre(int val)
{
    int pre;
    int rt=root;
    while (rt)
    {
        /*if (Treap[rt].k==val)
        {
            if (Treap[rt].ls>0)
            {
                rt=Treap[rt].ls;
                while (Treap[rt].ls>0)
                    rt=Treap[rt].rs;
                ans=rt;
            }
            break;
        }
        if (Treap[rt].k<val && Treap[rt].k>Treap[ans].k)
            ans=rt;
        if (Treap[rt].k>val) rt=Treap[rt].ls;
        else rt=Treap[rt].rs;*/
        if (Treap[rt].k<val)
    	{
    		pre=Treap[rt].k;
    		rt=Treap[rt].rs;
		}
		else rt=Treap[rt].ls;
    }
    //return Treap[ans].k;
    return pre;
}

int getnext(int val)
{
    int next;
    int rt=root;
    while (rt)
    {
        /*if (Treap[rt].k==val)
        {
            if (Treap[rt].rs>0)
            {
                rt=Treap[rt].rs;
                while (Treap[rt].rs>0)
                    rt=Treap[rt].ls;
                ans=rt;
            }
            break;
        }
        if (Treap[rt].k<val && Treap[rt].k>Treap[ans].k)
            ans=rt;
        if (Treap[rt].k>val) rt=Treap[rt].rs;
        else rt=Treap[rt].ls;*/
        if (Treap[rt].k>val)
        {
        	next=Treap[rt].k;
        	rt=Treap[rt].ls;
		}
		else rt=Treap[rt].rs;
    }
    //return Treap[ans].k;
    return next;
}
int main()
{
    build();        //先建个有边界的空树,或言初始化 
    scanf("%d",&n);
    while (n--)
    {
        scanf("%d %d",&opt,&x);
        if (opt==1) insert(root,x);
        else if (opt==2) del(root,x);
        else if (opt==3) printf("%d\n",getrank(root,x)-1);//Build的时候已经插入了两个极值边界,故会多出一个比x小的数,所以要减一 
        else if (opt==4) printf("%d\n",getranx(root,x+1));//Build的时候已经插入了两个极值边界,故查询的时候要把最小极值也考虑上 
        else if (opt==5) printf("%d\n",getpre(x));
        else if (opt==6) printf("%d\n",getnext(x));
    }
    return 0;
}

旋转型Treap的思路应该都差不多吧?不过代码实验似乎有挺多细节都不一样的。

我这个第一遍写的代码的样例输出是:

2147483647
2147483647
492737

之后翻了挺多教程、题解,最后大体按照天上一颗蛋 大佬的题解 进行修改的,被注释掉的是最开始写的,现在这个就是修改过的,不过输出还是不对,希望能有大佬帮忙看一下,谢谢啦!

2023/11/5 10:30
加载中...