zoukankan      html  css  js  c++  java
  • HNOI2004 宠物收养所 splay

    看清楚题意后居然一A了,这么长的代码一A对我来说还真是少见。

    突然弄懂了数组版splay的内存池的原理,还是很简单的。。。

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    const int MOD=1000000;
    
    int n;
    int op,x;
    struct Splay
    {
        ll key[maxn];
        int pre[maxn],ch[maxn][2],rt,tot1;
        int s[maxn],tot2;
        void newnode(int &r,int fa,ll k)
        {
            if(tot2) r=s[tot2--];
            else r=++tot1;
            key[r]=k;pre[r]=fa;
            MS0(ch[r]);
        }
        void rot(int x,int kind)
        {
            int y=pre[x];
            ch[y][kind^1]=ch[x][kind];
            pre[ch[x][kind]]=y;
            if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
            pre[x]=pre[y];
            ch[x][kind]=y;
            pre[y]=x;
        }
        void splay(int x,int goal)
        {
            while(pre[x]!=goal){
                if(pre[pre[x]]==goal) rot(x,ch[pre[x]][0]==x);
                else{
                    int y=pre[x],z=pre[y];
                    int kind=ch[y][0]==x,one=0;
                    if(ch[y][0]==x&&ch[z][0]==y) one=1;
                    if(ch[y][1]==x&&ch[z][1]==y) one=1;
                    if(one) rot(y,kind),rot(x,kind);
                    else rot(x,kind),rot(x,kind^1);
                }
            }
            if(goal==0) rt=x;
        }
        void Del()
        {
            if(!ch[rt][0]&&!ch[rt][1]) rt=0,tot1=tot2=0;
            else if(!ch[rt][0]) s[++tot2]=rt,rt=ch[rt][1],pre[rt]=0;
            else if(!ch[rt][1]) s[++tot2]=rt,rt=ch[rt][0],pre[rt]=0;
            else{
                int r=ch[rt][0];
                while(ch[r][1]) r=ch[r][1];
                splay(r,rt);
                s[++tot2]=rt;
                ch[r][1]=ch[rt][1];
                pre[ch[r][1]]=r;
                rt=r;
                pre[rt]=0;
            }
        }
        int Find(ll k)
        {
            if(rt==0) return 0;
            int r=rt,f=0;
            while(r){
                if(key[r]==k){
                    splay(r,0);
                    return 1;
                }
                f=r;
                r=ch[r][k>key[r]];
            }
            splay(f,0);
            return 0;
        }
        void Insert(ll x)
        {
            if(rt==0) newnode(rt,0,x);
            else{
                int r=rt,f=0;
                while(r){
                    if(key[r]==x){
                        splay(r,0);
                        return;
                    }
                    f=r;r=ch[r][x>key[r]];
                }
                newnode(ch[f][x>key[f]],f,x);
                splay(ch[f][x>key[f]],0);
            }
        }
        void init()
        {
            rt=tot1=0;
            tot2=0;
            MS0(pre);MS0(key);MS0(ch);
        }
        ll get_pre(int x)
        {
            if(!ch[x][0]) return -1;
            x=ch[x][0];
            while(ch[x][1]) x=ch[x][1];
            return key[x];
        }
        ll get_next(int x)
        {
            if(!ch[x][1]) return -1;
            x=ch[x][1];
            while(ch[x][0]) x=ch[x][0];
            return key[x];
        }
    };Splay A,P;
    
    int main()
    {
        freopen("in.txt","r",stdin);
        while(cin>>n){
            A.init();P.init();
            ll ans=0;
            REP(i,1,n){
                scanf("%d%d",&op,&x);
                if(op==0){
                    if(P.rt!=0){
                        if(P.Find(x)) P.Del();
                        else{
                            int y=P.key[P.rt],z;
                            if(x<y){
                                z=P.get_pre(P.rt);
                                if(z!=-1&&abs(x-z)<=abs(x-y)) P.Find(z);
                                P.Del();
                            }
                            else{
                                z=P.get_next(P.rt);
                                if(z!=-1&&abs(x-y)>abs(x-z)) P.Find(z);
                                P.Del();
                            }
                            if(z!=-1) ans+=min(abs(x-z),abs(x-y));
                            else ans+=abs(x-y);
                            //cout<<"x="<<x<<" y="<<y<<" z="<<z<<endl;
                            ans%=MOD;
                        }
                    }
                    else A.Insert(x);
                }
                else{
                    if(A.rt!=0){
                        if(A.Find(x)) A.Del();
                        else{
                            ll y=A.key[A.rt],z;
                            if(x<y){
                                z=A.get_pre(A.rt);
                                if(z!=-1&&abs(x-z)<=abs(x-y)) A.Find(z);
                                A.Del();
                            }
                            else{
                                z=A.get_next(A.rt);
                                if(z!=-1&&abs(x-y)>abs(x-z)) A.Find(z);
                                A.Del();
                            }
                            if(z!=-1) ans+=min(abs(x-z),abs(x-y));
                            else ans+=abs(x-y);
                            //cout<<"x="<<x<<" y="<<y<<" z="<<z<<endl;
                            ans%=MOD;
                        }
                    }
                    else P.Insert(x);
                }
            }
            cout<<ans%MOD<<endl;
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    IOS Your account already has a valid ios Distribution certification
    IOS no identity found
    IOS IPA打包遇到的问题:code signing is required for product type 'Application' in SDK 'iOS 8.1
    IOS 中的页面跳转(navigaitonController)+带自动返回
    IOS中懒加载
    IOS中点语法
    IOS中的UIImageView + ScrollView
    IOS中assign、copy 、retain、strong、weak等关键字的含义
    UIViewController的生命周期及iOS程序执行顺序
    uiview 的transitionWithView 方法使用
  • 原文地址:https://www.cnblogs.com/--560/p/5199748.html
Copyright © 2011-2022 走看看