treap 88pts T两个点,M一个点

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

yintaocheng @ 2023-10-01 10:18:10

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int s=0;
    bool f=false;
    char c=getchar();
    while(!isdigit(c))
    {
        if(c=='-')
            f=true;
        c=getchar(); 
    }
    while(isdigit(c))
    {
        s=(s<<3)+(s<<1)+c-'0';
        c=getchar();
    }
    return f?-s:s;
}
void write(int x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
}
int n,m,ans=0,lt=0,cnt=0;
struct node
{
    int ls,rs;
    int key,pri;
    int size;
}t[1000010];
void newnode(int x)
{
    cnt++;
    t[cnt].size=1;
    t[cnt].ls=t[cnt].rs=0;
    t[cnt].key=x;
    t[cnt].pri=rand();
}
void Update(int u)
{
    t[u].size=t[t[u].ls].size+t[t[u].rs].size+1;
}
void rotate(int &o,int d)
{
    int k;
    if(d==1)
    {
        k=t[o].rs;
        t[o].rs=t[k].ls;
        t[k].ls=o;
    }
    else
    {
        k=t[o].ls;
        t[o].ls=t[k].rs;
        t[k].rs=o;
    }
    t[k].size=t[o].size;
    Update(o);
    o=k;
}
void Insert(int &u,int x)
{
    if(u==0)
    {
        newnode(x);
        u=cnt;
        return;
    }
    t[u].size++;
    if(x>=t[u].key)
    {
        Insert(t[u].rs,x);
    }
    else
    {
        Insert(t[u].ls,x);
    }
    if(t[u].ls!=0&&t[u].pri>t[t[u].ls].pri)
    {
        rotate(u,0);
    }
    if(t[u].rs!=0&&t[u].pri>t[t[u].rs].pri)
    {
        rotate(u,1);
    }
    Update(u);
}
void Del(int &u,int x)
{
    t[u].size--;
    if(t[u].key==x)
    {
        if(t[u].ls==0&&t[u].rs==0)
        {
            u=0;
            return;
        }
        if(t[u].ls==0||t[u].rs==0)
        {
            u=t[u].ls+t[u].rs;
            return;
        }
        if(t[t[u].ls].pri<t[t[u].rs].pri)
        {
            rotate(u,0);
            Del(t[u].rs,x);
            return;
        }
        else
        {
            rotate(u,1);
            Del(t[u].ls,x);
            return;
        }
    }
    if(t[u].key>=x)
    {
        Del(t[u].ls,x);
    }
    else
    {
        Del(t[u].rs,x);
    }
    Update(u);
}
int Rank(int u,int x)
{
    if(u==0)
        return 0;
    if(x>t[u].key)
        return t[t[u].ls].size+1+Rank(t[u].rs,x);
    else
        return Rank(t[u].ls,x);
}
int kth(int u,int k)
{
    if(k==t[t[u].ls].size+1)
        return t[u].key;
    if(k>t[t[u].ls].size+1)
        return kth(t[u].rs,k-t[t[u].ls].size-1);
    if(k<=t[t[u].ls].size)
        return kth(t[u].ls,k);
}
int pre(int u,int x)
{
    if(u==0)
    {
        return 0;
    }
    if(t[u].key>=x)
    {
        return pre(t[u].ls,x);
    }
    int tmp=pre(t[u].rs,x);
    if(tmp==0)
    {
        return t[u].key;
    }
    return tmp;
}
int suc(int u,int x)
{
    if(u==0)
    {
        return 0;
    }
    if(t[u].key<=x)
    {
        return suc(t[u].rs,x);
    }
    int tmp=suc(t[u].ls,x);
    if(tmp==0)
    {
        return t[u].key;
    }
    return tmp;
}
signed main()
{
    srand(time(NULL));
    n=read();
    m=read();
    int root=0;
    for(int i=0;i<n;i++)
    {
        int x=read();
        Insert(root,x);
    }
    for(int i=0;i<m;i++)
    {
        int op=read(),x=read()^lt;
        if(op==1)
        {
            Insert(root,x);
        }
        else if(op==2)
        {
            Del(root,x);
        }
        else if(op==3)
        {
            ans^=(lt=(Rank(root,x)+1));
        }
        else if(op==4)
        {
            ans^=(lt=(kth(root,x)));
        }
        else if(op==5)
        {
            ans^=(lt=(pre(root,x)));
        }
        else
        {
            ans^=(lt=(suc(root,x)));
        }
    }
    write(ans);
    putchar('\n');
    return 0;
}

by PandaGhost @ 2023-10-01 11:09:26

struct node
{
    int ls,rs;
    int key,pri;
    int size;
}t[1000010];

1000010 改成 2000010 就可以了


by yintaocheng @ 2023-10-01 11:10:20

@PandaGhost 已AC,谢谢


by yintaocheng @ 2023-10-01 11:12:21

@PandaGhost 我这里这本算法竞赛书上写的好像有点问题,kth最后一个if没有return,我没加return只有44pts,加上就过了,明天给你看一下


by PandaGhost @ 2023-10-01 11:28:48

@yintaocheng 我看过代码了,确实很抽象


|