splay 30pts求助,直接复制p3369的ac代码改一改都不行,枯了

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

jixiang @ 2021-11-14 08:53:23

#include<bits/stdc++.h>
using namespace std;
const int N= 2e6+9;
const int INF = 2e9+5;
int root,idx;
int n,m;
int li,ri;

struct node
{
    int s[2];
    int v,p,siz,cnt;
    void init(int _p,int _v)
    {
        p= _p;
        v= _v;
        siz= 1;
        cnt= 1;
    }
}tr[N];

template <typename T> void read(T &x)
{
    x= 0; bool f=1;
    char ch= getchar();
    while (ch<'0'|| ch > '9'){if(ch=='-')f=0; ch= getchar();}
    while (ch>='0'&&ch<='9'){x= (x<<1)+ (x<<3)+ ch - '0'; ch=  getchar();}
    if(!f)x*=-1;
}

void up(int p)
{
    tr[p].siz= tr[tr[p].s[1]].siz+ tr[tr[p].s[0]].siz +tr[p].cnt;
}

void spin(int x)
{
    int y= tr[x].p;
    int z= tr[y].p;
    int k= tr[y].s[1]==x;
    tr[z].s[tr[z].s[1]==y] =x; tr[x].p= z;
    tr[tr[x].s[k^1]].p= y; tr[y].s[k]= tr[x].s[k^1];
    tr[x].s[k^1]= y; tr[y].p= x;
    up(y); up(x);
}

void splay(int x,int k)
{
    while (tr[x].p!=k)
    {
        int y= tr[x].p;
        int z= tr[y].p;
        if(z!=k)
        {
            if((tr[y].s[1]==x) ^ (tr[z].s[1]==y))spin(x);
            else spin(y);
        }
        spin(x);
    }
    if(!k)root= x;
}

void istop(int val)
{
    int u= root;
    if(!u)return ;
    while(tr[u].v!=val && tr[u].s[val> tr[u].v]) u= tr[u].s[val > tr[u].v];

    splay(u,0);
}

void plug(int val)
{
    int u= root; int p =0;
    while (u && tr[u].v!=val) p=u, u= tr[u].s[val>tr[u].v];
    if(u)tr[u].cnt++;
    else
    {
        u= ++idx;
        if(p)tr[p].s [val> tr[p].v] = u;
        tr[u].init(p,val);
    }
    splay(u,0);
}

int getnxt(int val,int jud)
{
    istop(val);
    int u= root;
    if(tr[u].v > val && jud) return u;
    if(tr[u].v < val && !jud) return u;
    u= tr[u].s[jud];
    while (tr[u].s[jud ^ 1])u= tr[u]. s[jud ^ 1];
    return u;
}

int get_v_byk(int x)
{
    int u= root;
    while (tr[u].siz< x)return 0;
    while(1)
    {
       int ls =tr[u].s[0];
       if(x >  tr[ls].siz+ tr[u].cnt)
       {
           x-= tr[ls].siz+ tr[u].cnt;
           u= tr[u].s[1];
       }
       else if(tr[ls].siz>=x) u= ls;
       else return tr[u].v;
    }
    return -1;
}

int get_k_byv(int val)
{
    istop(val);
    return tr[tr[root].s[0]].siz;
}

void del(int val)
{
    int pre = getnxt (val,0);
    int nxt = getnxt (val,1);
    splay (pre ,0); splay(nxt,pre);
    int dtar = tr[nxt].s[0];

    if(tr[dtar].cnt>1)
    {
        tr[dtar].cnt--;
        splay(dtar,0);
    }
    else tr[nxt].s[0]= 0;
}

signed main()
{
    read(n);
    read(m);

    int res= 0;
    int last = 0;
    plug(-INF);
    plug(INF);
    for(int i= 1;i<=n;i++)read(last),plug(last);
    last = 0;
    for(int i= 1;i<=m;i++)
    {
        int op,x;
        read(op);
        read(x);
        x^= last;
        if(op==1) plug(x);
        else if(op==2)del(x);
        else if(op==3)last = get_k_byv(x)+1, res ^= last ;//printf("%d\n",get_k_byv(x));
        else if(op==4)last = get_v_byk(x+1), res ^= last ;//printf("%d\n",get_v_byk(x+1));
        else if(op==5)last = tr[getnxt(x,0)].v, res ^= last ;//printf("%d\n",tr[getnxt(x,0)].v);
        else last = tr[getnxt(x,1)].v, res ^= last ;//printf("%d\n",tr[getnxt(x,1)].v);
    }
    printf("%d\n",res);
    return 0;
}

by SDNetFriend @ 2021-11-14 09:41:00

注意这个加强版好像查前驱后继或者排名的时候这个数可能不存在的,可能需要修改这几个函数。


by jixiang @ 2021-11-14 11:28:31

@SDNetFriend 哦哦,果真如此,题面其实也说了下,忽略了~ 谢谢大佬!


|