splay板子 RE*7,TLE*3,求调

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

artalter @ 2022-02-12 07:10:54

RT

#include<bits/stdc++.h>
using namespace std;
const long long maxn = 200005;
#define root t[0].ch[1]
long long tot;
struct tree
{
    long long w;
    long long fa;
    long long ch[2];
    long long cnt;
    long long size;
}t[maxn];
void update(long long x)
{
    t[x].size=t[x].cnt+t[t[x].ch[0]].size+t[t[x].ch[1]].size;
}
long long ff(long long x)
{
    return t[t[x].fa].ch[1]==x;
}
void connect(long long x,long long y,long long now)
{
    t[y].ch[now]=x;
    t[x].fa=y;
}
void ronate(long long x)
{
    long long y=t[x].fa;
    long long z=t[y].fa;
    long long ys=ff(y);
    long long xs=ff(x);
    connect(t[x].ch[xs^1],y,xs);
    connect(y,x,xs^1);
    connect(x,z,ys);
    update(y);
    update(x);
}
void splay(long long x,long long y)
{
    y=t[y].fa;
    while(t[x].fa!=y)
    {
        if(t[t[x].fa].fa==y)ronate(x);
        else if(ff(x)==ff(t[x].fa))ronate(t[x].fa),ronate(x);
        else ronate(x),ronate(x);
    }
}
void newpoint(long long w,long long fa)
{
    tot++;
    t[tot].fa=fa;
    t[tot].w=w;
    t[tot].size = t[tot].cnt = 1;
}
void insert(long long x)
{
    long long now=root;
    if(root==0)
    {
        newpoint(x,0);
        root=tot;
    }else
    {
        while(1)
        {
            t[now].size++;
            if(t[now].w == x)
            {
                t[now].cnt++;
                splay(now,root);
                return;
            }
            long long nxt=x<t[now].w?0:1;
            if(!t[now].ch[nxt])
            {
                newpoint(x,now);
                t[now].ch[nxt]=tot;
                splay(tot,root);
                return;
            }
            now=t[now].ch[nxt];
        }
    }
}
long long find(long long x)
{
    long long now=root;
    while(1)
    {
        if(!now)return 0;
        if(t[now].w==x)
        {
            splay(now,root);
            return now;
        }
        long long nxt= x<t[now].w?0:1;
        now=t[now].ch[nxt];
    }
}
void delet(long long x)
{
    long long pos = find(x);
    if(!pos)return;
    if(t[pos].cnt>1)
    {
        t[pos].size--;
        t[pos].cnt--;
        return;
    }else
    {
        if(!t[pos].ch[0]&&!t[pos].ch[1])
        {
            root=0;
            return;
        }else if(!t[pos].ch[0])
        {
            root=t[pos].ch[1];
            t[root].fa=0;
            return;
        }else if(!t[pos].ch[1])
        {
            root=t[pos].ch[0];
            t[root].fa=0;
        }else if(!t[pos].ch[0])
        {
            root=t[pos].ch[1];
            t[root].fa=0;
        }else
        {
            long long left=t[pos].ch[0];
            while(t[left].ch[1])left=t[left].ch[1];
            splay(left,t[pos].ch[0]);
            connect(t[pos].ch[1],left,1);
            connect(left,0,1);
            update(left);
        }
    }
}
long long rak(long long x)
{
    long long pos=find(x);
    return t[t[pos].ch[0]].size+1;
}
long long arank(long long x)
{
    long long now=root;
    while(1)
    {
        long long used=t[now].size-t[t[now].ch[1]].size;
        if(x>t[t[now].ch[0]].size&&x<=used)
        {
            break;
        }
        if(x<used)
        {
            now=t[now].ch[0];
        }else
        {
            x=x-used;
            now=t[now].ch[1];
        }
    }
    splay(now,root);
    return t[now].w;
}
long long lower(long long x)
{
    long long now=root;
    long long ans=-10000000000000000;
    while(now)
    {
        if(t[now].w<x&&t[now].w>ans)
        {
            ans=t[now].w;
        }
        if(x>t[now].w)now=t[now].ch[1];
        else now=t[now].ch[0];
    }
    return ans;
}
long long upper(long long x)
{
    long long now=root;
    long long ans=10000000000000000;
    while(now)
    {
        if(t[now].w>x&&t[now].w<ans)ans=t[now].w;
        if(x<t[now].w)now=t[now].ch[0];
        else now=t[now].ch[1];
    }
    return ans;
}
int main()
{
    long long n,m;
    cin>>n>>m;
    for(long long i=1;i<=n;i++)
    {
        long long x;
        cin>>x;
        insert(x);
    }
    long long last=0,k=0;
    for(int i=1;i<=m;i++)
    {
        long long x,opt;
        cin>>opt>>x;
        x^=last;
        if(opt==1)
        {
            insert(x);
        }else if(opt ==2)
        {
            delet(x);
        }else if(opt==3)
        {
            if(find(x))
            {
                last=rak(x);
            }else{
                last=rak(lower(x))+1;
            }
        }else if(opt==4)
        {
            last=arank(x);
        }else if(opt==5)
        {
            last=lower(x);
        }else if(opt==6)
        {
            last=upper(x);
        }
        if(opt>=3)k^=last;
    }
    cout<<k;
    return 0;
}

by artalter @ 2022-02-12 07:19:02

此贴已结,把rak函数改成这样,再开大范围后,成功AC


long long rak(long long x)
{
    insert(x);
    long long pos=find(x);
    int k= t[t[pos].ch[0]].size+1;
    delet(x);
    return k;
}
else if(opt==3)
{
   last=rak(x);
}

by SoyTony @ 2022-02-12 07:52:04

恭喜(doge)


|