菜鸡求助,只有底下那一组特殊数据AC了,0分
查看原帖
菜鸡求助,只有底下那一组特殊数据AC了,0分
896371
xduliu楼主2024/9/24 19:20
#include<cstdio>
using namespace std;
int n,op,x,root,t,l;
struct dian
{
    int left,right,leftnum,rightnum,value;
    dian():left(-1),right(-1),leftnum(0),rightnum(0),value(-1) {}
};
struct dian d[10007];
int c1(int x)//如果小于根节点值,则往左走,无其他改变;若大于根节点值,则往右走,且用累加器累加左子树大小+1(根节点)记录排名;若等于,则累加器值即为所求
{
    struct dian dd;
    dd.value=x;
    int roo=root,sum=0;
    while(1)
    {
        if(x<d[roo].value)
            if(d[roo].left!=-1)
                roo=d[roo].left;
            else
                return -2147483647;    
        else if(x>d[roo].value)
        {
            sum+=1+d[roo].leftnum;
            if(d[roo].right!=-1)
                roo=d[roo].right;
            else
                return -2147483647;    
        }
        else
            return sum+d[roo].leftnum+1;
    }
}
int c2(int x)//如果左子树大小+1大于要找的名次,说明要找的在左子树,即在左子树中去找排X的;若小于,说明在右子树中,是在右子树中找名次为x-左子树大小-1(根节点)的;若等于,则返回此节点的value值就好
{
    if(x<=0||x>l)
        return -2147483647;
    int roo=root,sum;              
    while(1)
    {//printf("t2\n");
        sum=d[roo].leftnum;       
        if(x<sum+1)
            roo=d[roo].left;
        else if(x>sum+1)
        {
            x-=d[roo].leftnum+1;
            roo=d[roo].right;
        }
        else if(x==sum+1)
            return d[roo].value;
    }
}
inline int c3(int x)//c3c4应该有两种写法的,按书上说的需要先找到排名再推节点,应该是o(2logn),但如果我直接找节点,再直接找左右子树,应该只有o(logn),大概会更快?这个思路不通,因为前驱和后继不一定就是左右子结点,比如后继可能会是左子节点的右子结点
{
    int cc=c1(x);
    if(cc!=-2147483647)
        return c2(cc-1);
    else 
        return cc;     
}
inline int c4(int x)
{
    int cc=c1(x);
    if(cc!=-2147483647)
        return c2(cc+1);
    else 
        return 2147483647;    
}
void c5(int x)
{
    struct dian dd;
    dd.value=x;
    int roo=root;
    if(!l)
    {
        d[l++]=dd;
        return;
    }
    while(1)
    {
        if(x<d[roo].value)
        {
            d[roo].leftnum++;
            if(d[roo].left==-1)
            {
                d[roo].left=l;
                d[l++]=dd;
                return;
            }
            else
                roo=d[roo].left;
        }
        else if(x>d[roo].value)
        {
            d[roo].rightnum++;
            if(d[roo].right==-1)
            {
                d[roo].right=l;
                d[l++]=dd;
                return;
            }
            else
                roo=d[roo].right;
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        scanf("%d%d",&op,&x);
        if(op==5)
            c5(x);
        else if(op==4)
            printf("%d\n",c4(x));
        else if(op==3)
            printf("%d\n",c3(x));            
        else if(op==2)
            printf("%d\n",c2(x));
        else if(op==1)
            printf("%d\n",c1(x));    
    }
    //for(int i=0;i<l;i++)printf("\n序列%d 左子树数量为%d 右子树数量为%d 左子节点为%d 右子结点为%d",d[i].value,d[i].leftnum,d[i].rightnum,d[i].left,d[i].right);
    return 0;
}
2024/9/24 19:20
加载中...