洛谷 P1503鬼子进村

题目描述

可以用平衡树维护被摧毁的点,每次询问就是找这个数的前驱和后继(数据很水暴力都能过)。

#include
#include
using namespace std;
const int N=5e4+7;
int n,m,sz,rot;
int fat[N],son[N][2],siz[N],key[N];
int s[N],top;
int qread()
{
    int x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9')ch=getchar();
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x;
}
void Update(int rt)
{
    siz[rt]=siz[son[rt][1]]+siz[son[rt][0]]+1;
}
void Rotate(int x,int &rt)
{
    int a=fat[x],b=fat[a],l=son[a][1]==x,r=l^1;
    if(a==rt)rt=x;
    else son[b][son[b][1]==a]=x;
    fat[son[x][r]]=a;fat[a]=x;fat[x]=b;
    son[a][l]=son[x][r];son[x][r]=a;
    Update(a);Update(x);
}
void Splay(int x,int &rt)
{
    while(x!=rt)
    {
        int a=fat[x],b=fat[a];
        if(a!=rt)
            if((son[a][1]==x)^(son[b][1]==a))
                Rotate(x,rt);
            else Rotate(a,rt);
        Rotate(x,rt);
    }
}
void Insert(int v,int k)
{
    int fa=0;
    while(k && key[k]!=v)
        fa=k,k=son[k][key[k]<v];
    k=++sz;
    fat[k]=fa;key[k]=v;
    siz[k]=1;
    if(fa)son[fa][key[fa]k;
    Splay(k,rot);
}
void Find(int x,int k)
{
    while(son[k][key[k]key[k])
        k=son[k][key[k]<x];
    Splay(k,rot);
}
void Delete(int x)
{
    Find(x,rot);
    if(son[rot][0] && son[rot][1])
    {
        int tmp=rot,k=son[rot][1];
        rot=k;
        while(son[k][0])k=son[k][0];
        siz[k]+=siz[son[tmp][0]];
        fat[son[tmp][0]]=k;son[k][0]=son[tmp][0];
        Splay(k,rot);
    }
    else rot=son[rot][0]+son[rot][1];
    fat[rot]=0;
}
int GetNxt(int x,int f)
{
    if((key[rot]>x && f) || (key[rot]f))
        return rot;
    int k=son[rot][f];
    while(son[k][f^1])k=son[k][f^1];
    return k;
}
int main()
{
    scanf("%d%d",&n,&m);
    char p[2];int x,l,r;
    Insert(0,rot);Insert(n+1,rot);
    while(m--)
    {
        scanf("%s",p);
        if(p[0]=='D')
        {
            x=qread();
            Insert(x,rot);
            s[++top]=x;
        }
        else if(p[0]=='R')Delete(s[top--]);
        else
        {
            x=qread();
            Find(x,rot);
            if(key[rot]==x)puts("0");
            else
            {
                l=key[GetNxt(x,0)];r=key[GetNxt(x,1)];
                printf("%d\n",r-l-1);
            }
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/LeTri/p/8746001.html

你可能感兴趣的:(洛谷 P1503鬼子进村)