splay求助

P6136 【模板】普通平衡树(数据加强版)

hewo @ 2021-02-01 11:19:47

只过了1 4

3 WA了

其他全TLE

#include<bits/stdc++.h>
using namespace std;
#define inf 0x7fffffff
const int MX=10000010;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
//cnt 当前节点重复个数
int tree[MX][2],value[MX],father[MX],size[MX],cnt[MX];
int root;
int tot=0;
int lans[MX];
int ks=0;
inline int creat(int v)
{
    value[++tot]=v;
    size[tot]=cnt[tot]=1;
    return tot;
}
inline int get_lr(int x)//获得左右信息
{
    return tree[father[x]][1]==x;//left-->0 right-->1
}
inline void pushup(int x)
{
    if(x)
    {
        size[x]=size[tree[x][0]]+size[tree[x][1]]+cnt[x];
    }
}
inline void rotate(int x)
{
    int fa=father[x],gfa=father[father[x]];
    int p=get_lr(x); 
    tree[fa][p]=tree[x][p^1],father[tree[fa][p]]=fa;
    father[fa]=x;
    tree[x][p^1]=fa;
    father[x]=gfa;
    if(gfa)
    {
        tree[gfa][tree[gfa][1]==fa]=x;
    }
    pushup(fa),pushup(x);

}
inline void splay(int x)
{
    for(int fa;fa=father[x];rotate(x))
    {
        if(father[fa])
        {
            rotate(get_lr(x)==get_lr(fa)?fa:x);
        }
    }
    root=x;
}
inline void insert(int x)
{
    //int fa=father[x],gfa=father[fa];
    if(!root)
    {
        value[root=++tot]=x;
        size[tot]=cnt[tot]=1;
        return ;
    }
    int now=root,fa=0;
    while(1)
    {
        if(value[now]==x)
        {
            cnt[now]++;
            pushup(now),pushup(fa);
            splay(now);
            return ;
        }
        fa=now,now=tree[now][x>value[now]];
        if(!now)
        {
            father[++tot]=fa,value[tot]=x;
            size[tot]=cnt[tot]=1;
            tree[fa][value[fa]<x]=tot;
            pushup(fa);
            splay(tot);
            return ;
        }
    }
}
inline int getrank(int x)
{
    if(!root) return 0;
    int now=root,ans=0; 
    while(now)
    {
        if(x<value[now])
        {
            now=tree[now][0];
        }
        else
        {
            ans+=size[tree[now][0]];
            if(x==value[now])
            {
                splay(now);
                return ans+1;
            }
            ans+=cnt[now],now=tree[now][1];
        }
    }
    return ans+1;
}
inline int getnum(int x)
{
    if(!root) return 0;
    int now=root;
    while(1)
    {
        if(x<=size[tree[now][0]]) now=tree[now][0];
        else
        {
            int p=size[tree[now][0]]+cnt[now];
            if(x<=p) return value[now];
            x-=p;
            now=tree[now][1];
        }
    }
}
/*
inline int getpre(int x)
{
    int now=root,ans=0;
    while(now)
    {
        if(x>value[now])
        {
            ans=value[now];
            now=tree[now][1];
        }
        else
        {
            now=tree[now][0];
        }
    }
}
inline int getsuf(int x)
{
    int now=root,ans=0;
    while(now)
    {
        if(x<value[now])
        {
            ans=value[now];
            now=tree[now][0];
        }
        else 
        {
            now=tree[now][1];
        }
    }
}
*/
inline int getpre()
{
    int now=tree[root][0];
    while(tree[now][1])
    {
        now=tree[now][1];
    }
    return now;
}
inline int getsuf()
{
    int now=tree[root][1];
    while(tree[now][0]) 
    {
        now=tree[now][0];
    }
    return now;
}
inline void remove(int x)
{
    getrank(x);
    if(cnt[root]>1)
    {
        cnt[root]--;
        pushup(root);
        return ;
    }
    if(!tree[root][0]*tree[root][1]){
        root=tree[root][0]+tree[root][1];
        father[root]=0; return;
    }
    /*
    else if(!tree[root][0])
    {
        root=tree[root][0];
        father[tree[root][0]]=0;
        return ;
    }
    else if(!tree[root][1])
    {
        root=tree[root][1];
        father[tree[root][1]]=1;
        return ;
    }
    */
    splay(getpre());
    tree[root][1]=tree[tree[root][1]][1];
    father[tree[root][1]]=root;
    pushup(root);
}
int main()
{
    int n,m;
    n=read(),m=read();
    for(int i=1;i<=n;i++)
    {
        int inb;
        inb=read();
        insert(inb);
    }
    for(int i=1;i<=m;i++)
    {
        int ina,inb;
        ina=read(),inb=read();
        if(ina==1)
        {
            insert(inb);
        }
        else if(ina==2)
        {
            remove(inb);
        }
        else if(ina==3)
        {
            inb=(inb xor lans[ks]);
            //cout<<inb<<endl;
            lans[++ks]=getrank(inb);
        }
        else if(ina==4)
        {
            inb=(inb xor lans[ks]);
            lans[++ks]=getnum(inb);
            //cout<<endl<<inb<<"    "<<lans[ks]<<endl;
        }
        else if(ina==5)
        {
            inb=(inb xor lans[ks]);
            //cout<<inb<<endl;
            insert(inb);
            lans[++ks]=value[getpre()];
            remove(inb);
            //cout<<endl<<inb<<"    "<<lans[ks]<<endl;
        }
        else if(ina==6)
        {
            inb=(inb xor lans[ks]);
            //cout<<inb<<endl;
            insert(inb);
            lans[++ks]=value[getsuf()];
            remove(inb);
            //cout<<endl<<inb<<"    "<<lans[ks]<<endl;
        }
    }
    int rans=0;
    for(int i=2;i<=ks;i++)
    {
        lans[i]=(lans[i] xor lans[i-1]);
    }
    cout<<lans[ks]<<endl;
    return 0;
}

by EDqwq @ 2021-02-01 11:30:03

虽然马蜂清奇,但是确信您的splay和getpre和getsuf没有错,其他一个看不懂


by hewo @ 2021-02-01 11:54:18

@林深时x见鹿

这个代码过了弱化版的,只是微调了一下(码风改不过来了


|