[BZOJ1058][ZJOI2007]报表统计

原题地址

Splay.

看着自己的早期代码也是醉了…

AC code:

#include <cstdio>
#include <cstdlib>
#include <cstring>
const int N=1000010;
int n,m;
int cnt[N];

int Min(int x,int y)
{
    return x<y?x:y;
}

int Min(int x,int y,int z)
{
    return Min(Min(x,y),z);
}

int Abs(int x)
{
    return x>0?x:-x;
}

struct Vnode
{
    int val;
    Vnode *Prev,*Ch[2];
};

struct Nnode
{
    int n1,n2,val,k,mink;
    Nnode *Prev,*Ch[2];
};

struct V_Splay
{
    int ans;
    Vnode *NIL,*root,*pool;

    V_Splay(int size)
    {
        pool=(Vnode*)malloc(size*sizeof(Vnode));
        NIL=root=pool++;
        NIL->Ch[0]=NIL->Ch[1]=NULL;
        ans=1<<30;
    }

    void rotate(Vnode *x,bool type)
    {
        Vnode *y=x->Prev,*z=y->Prev,*b=x->Ch[type^1];
        b->Prev=y;
        y->Prev=x;
        x->Prev=z;
        y->Ch[type]=b;
        x->Ch[type^1]=y;
        if(z->Ch[0]==y) z->Ch[0]=x;
        if(z->Ch[1]==y) z->Ch[1]=x;
    }

    void splay(Vnode *x,Vnode *obj)
    {
        while(x->Prev!=obj)
        {
            Vnode *y=x->Prev,*z=y->Prev;
            if(z==NIL){
                if(y->Ch[0]==x) rotate(x,0);
                else rotate(x,1);
            }
            else{
                if(z->Ch[0]==y&&y->Ch[0]==x){
                    rotate(y,0);
                    rotate(x,0);
                }
                else if(z->Ch[1]==y&&y->Ch[1]==x){
                    rotate(y,1);
                    rotate(x,1);
                }
                else if(z->Ch[1]==y){
                    rotate(x,0);
                    rotate(x,1);
                }
                else{
                    rotate(x,1);
                    rotate(x,0);
                }
            }
        }
        if(obj==NIL) root=x;
    }

    void insert(int key)
    {
        _insert(&root,key,NIL);
    }

    void _insert(Vnode **p,int key,Vnode *last)
    {
        while(1)
        {
            if(*p==NIL){
                *p=pool++;
                (*p)->val=key;
                (*p)->Prev=last;
                (*p)->Ch[0]=(*p)->Ch[1]=NIL;
                splay(*p,NIL);
                Vnode *t=root->Ch[0];
                while(t!=NIL&&t->Ch[1]!=NIL) t=t->Ch[1];
                if(t!=NIL) ans=Min(ans,root->val-t->val);
                t=root->Ch[1];
                while(t!=NIL&&t->Ch[0]!=NIL) t=t->Ch[0];
                if(t!=NIL) ans=Min(ans,t->val-root->val);
                return ;
            }
            bool flag=key>(*p)->val;
            last=*p;
            p=&(*p)->Ch[flag];
        }
    }
};

struct N_Splay
{
    int ans;
    Nnode *NIL,*root,*pool;

    N_Splay(int size)
    {
        pool=(Nnode*)malloc(size*sizeof(Nnode));
        NIL=root=pool++;
        NIL->Ch[0]=NIL->Ch[1]=NULL;
        NIL->mink=ans=1<<30;
    }

    void rotate(Nnode *x,bool type)
    {
        Nnode *y=x->Prev,*z=y->Prev,*b=x->Ch[type^1];
        b->Prev=y;
        y->Prev=x;
        x->Prev=z;
        y->Ch[type]=b;
        x->Ch[type^1]=y;
        if(z->Ch[0]==y) z->Ch[0]=x;
        if(z->Ch[1]==y) z->Ch[1]=x;
        x->mink=Min(x->k,x->Ch[0]->mink,x->Ch[1]->mink);
        y->mink=Min(y->k,y->Ch[0]->mink,y->Ch[1]->mink);
    }

    void splay(Nnode *x,Nnode *obj)
    {
        while(x->Prev!=obj){
            Nnode *y=x->Prev,*z=y->Prev;
            if(z==NIL){
                if(y->Ch[0]==x) rotate(x,0);
                else rotate(x,1);
            }
            else{
                if(z->Ch[0]==y&&y->Ch[0]==x){
                    rotate(y,0);
                    rotate(x,0);
                }
                else if(z->Ch[1]==y&&y->Ch[1]==x){
                    rotate(y,1);
                    rotate(x,1);
                }
                else if(z->Ch[1]==y){
                    rotate(x,0);
                    rotate(x,1);
                }
                else{
                    rotate(x,1);
                    rotate(x,0);
                }
            }
        }
        if(obj==NIL) root=x;
    }

    void insert(int key,int num1,int num2)
    {
        _insert(&root,key,num1,num2,NIL);
    }

    void _insert(Nnode **p,int key,int num1,int num2,Nnode *last)
    {
        while(1)
        {
            if(*p==NIL){
                *p=pool++;
                (*p)->val=key;
                (*p)->n1=num1;
                (*p)->n2=num2;
                (*p)->Prev=last;
                (*p)->mink=(*p)->k=1<<30;
                (*p)->Ch[0]=(*p)->Ch[1]=NIL;
                splay(*p,NIL);
                Nnode *t=root->Ch[0];
                while(t!=NIL&&t->Ch[1]!=NIL) t=t->Ch[1];
                if(t!=NIL) root->k=Abs(root->val-t->val);
                t=root->Ch[1];
                while(t!=NIL&&t->Ch[0]!=NIL) t=t->Ch[0];
                if(t!=NIL) t->k=Abs(root->val-t->val);
                while(t!=NIL){
                    t->mink=Min(t->k,t->Ch[0]->mink,t->Ch[1]->mink);
                    t=t->Prev;
                }
                ans=root->mink=Min(root->k,root->Ch[0]->mink,root->Ch[1]->mink);
                return ;
            }
            if(num1<(*p)->n1){
                last=*p;
                p=&(*p)->Ch[0];
            }
            else{
                last=*p;
                p=&(*p)->Ch[1];
            }
        }
    }
};

int main()
{
    scanf("%d%d",&n,&m);
    V_Splay T1(N);
    N_Splay T2(N);
    for(int i=1;i<=n;i++){
        int t;
        scanf("%d",&t);
        T1.insert(t);
        T2.insert(t,i,0);
    }
    for(int i=1;i<=m;i++){
        char s[101];
        scanf("%s",s);
        if(!strcmp(s,"MIN_GAP")) printf("%d\n",T2.ans);
        else if(!strcmp(s,"MIN_SORT_GAP")) printf("%d\n",T1.ans);
        else{
            int p,t;
            scanf("%d%d",&p,&t);
            T1.insert(t);
            T2.insert(t,p,++cnt[p]);
        }
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值