• bzoj1503[NOI2004]郁闷的出纳员——Splay


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1503

    好奇怪呀!为什么而TLE?

    各种修改终于卡时过了。可是大家比我快多了呀?难道是因为自己把相同节点弄成一个节点、记了一个cnt的缘故?

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=1e5+5;
    int n,c[N][2],fa[N],siz[N],cnt[N],ans,tot,rt;
    ll lm,val[N],fx;
    void pushup(int k){siz[k]=siz[c[k][0]]+siz[c[k][1]]+cnt[k];}
    //void insert(int &k,int f,ll s)
    //{
    //  if(!k){k=++tot;siz[k]=1;cnt[k]=1;val[k]=s;fa[k]=f;return;}
    //  if(s==val[k]){cnt[k]++;siz[k]++;return;}
    //  int d=(s>val[k]);insert(c[k][d],k,s);
    //  pushup(k);
    //}
    void rotate(int x,int &k)
    {
        int y=fa[x],z=fa[y];
        if(y==k)k=x;
        else c[z][y==c[z][1]]=x;
        int d=(x==c[y][1]);
        fa[x]=z;fa[y]=x;fa[c[x][!d]]=y;//fa[x]=z在这里,不是43行 
        c[y][d]=c[x][!d];c[x][!d]=y;
        pushup(y);pushup(x);
    }
    void splay(int x,int &k)
    {
        while(x!=k)
        {
            int y=fa[x],z=fa[y];
            if(y!=k)
            {
                if((c[y][0]==x)^(c[z][0]==y))rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
    }
    void insert(ll s)
    {
        if(!rt){rt=++tot;siz[rt]=1;cnt[rt]=1;val[rt]=s;fa[rt]=0;return;}
        int z,p=rt;
        while(p)
        {
            z=p;
            siz[p]++;
            if(s==val[p]){cnt[p]++;splay(p,rt);return;}//
            p=c[p][s>val[p]];
        }
        p=++tot;cnt[p]=1;siz[p]=1;val[p]=s;
        fa[p]=z;c[z][s>val[z]]=p;
        splay(p,rt);//
    }
    int find(int k,ll s)
    {
        if(!k)return 0;
        if(val[k]==s)return k;
        int d=(s>val[k]);
        return find(c[k][d],s);
    }
    void del(ll s)
    {
        int k=find(rt,s);if(!k)return;//
        if(k!=rt)splay(k,rt);
        ans+=siz[c[k][0]];
        if(cnt[k]==1)rt=c[k][1];
        else {
            cnt[k]--;fa[c[k][0]]=0;c[k][0]=0;pushup(k);
        }
    }
    ll query(int k,int s)
    {
        if(siz[c[k][1]]<s&&siz[c[k][1]]+cnt[k]>=s)return val[k];
        if(siz[c[k][1]]>=s)return query(c[k][1],s);
        else return query(c[k][0],s-siz[c[k][1]]-cnt[k]);//
    }
    int main()
    {
        scanf("%d%lld",&n,&lm);char ch;ll tp;
        while(n--)
        {
            cin>>ch;scanf("%lld",&tp);
            if(ch=='I')
            {
                if(tp-fx<lm)continue;
    //          else insert(rt,0,tp-fx);
                else insert(tp-fx);
            }
            else if(ch=='A')fx+=tp,lm-=tp;
            else if(ch=='S')
            {
                fx-=tp;lm+=tp;
    //          insert(rt,0,lm);
                insert(lm);del(lm);
            }
            else {
                if(tp>siz[rt])printf("-1
    ");
                else printf("%lld
    ",query(rt,tp)+fx);
            }
        }
        printf("%d",ans);
        return 0;
    }
    View Code
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=1e5+5;
    int n,c[N][2],fa[N],siz[N],cnt[N],ans,tot,rt;
    ll lm,val[N],fx;
    void pushup(int k){siz[k]=siz[c[k][0]]+siz[c[k][1]]+cnt[k];}
    //void insert(int &k,int f,ll s)
    //{
    //  if(!k){k=++tot;siz[k]=1;cnt[k]=1;val[k]=s;fa[k]=f;return;}
    //  if(s==val[k]){cnt[k]++;siz[k]++;return;}
    //  int d=(s>val[k]);insert(c[k][d],k,s);
    //  pushup(k);
    //}
    void rotate(int x,int &k)
    {
        int y=fa[x],z=fa[y];
        if(y==k)k=x;
        else c[z][y==c[z][1]]=x;
        int d=(x==c[y][1]);
        fa[x]=z;fa[y]=x;fa[c[x][!d]]=y;//fa[x]=z在这里,不是43行 
        c[y][d]=c[x][!d];c[x][!d]=y;
        pushup(y);pushup(x);
    }
    void splay(int x,int &k)
    {
        while(x!=k)
        {
            int y=fa[x],z=fa[y];
            if(y!=k)
            {
                if((c[y][0]==x)^(c[z][0]==y))rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
    }
    void insert(ll s)
    {
        if(!rt){rt=++tot;siz[rt]=1;cnt[rt]=1;val[rt]=s;fa[rt]=0;return;}
        int z,p=rt;
        while(p)
        {
            z=p;
            siz[p]++;
            if(s==val[p]){cnt[p]++;splay(p,rt);return;}//
            p=c[p][s>val[p]];
        }
        p=++tot;cnt[p]=1;siz[p]=1;val[p]=s;
        fa[p]=z;c[z][s>val[z]]=p;
        splay(p,rt);//
    }
    //int find(int k,ll s)
    //{
    //  if(!k)return 0;
    //  if(val[k]==s)return k;
    //  int d=(s>val[k]);
    //  return find(c[k][d],s);
    //}
    //void del(ll s)
    //{
    //  int k=find(rt,s);if(!k)return;//
    //  if(k!=rt)splay(k,rt);
    //  ans+=siz[c[k][0]];
    //  if(cnt[k]==1)rt=c[k][1];
    //  else {
    //      cnt[k]--;fa[c[k][0]]=0;c[k][0]=0;pushup(k);
    //  }
    //}
    int del(int &k,int f)
    {
        if(!k)return 0;//
        int rtn=0;
        if(val[k]<lm||(val[k]==lm&&cnt[k]==1))
        {
            rtn=del(c[k][1],k)+siz[c[k][0]]+cnt[k];
            siz[c[k][1]]=siz[k]-rtn;
            k=c[k][1];fa[k]=f;
        }
        else{
            if(val[k]==lm)cnt[k]--,rtn++;
            rtn+=del(c[k][0],k);
            siz[k]-=rtn;
        }
        return rtn;
    }
    ll query(int k,int s)
    {
        if(siz[c[k][1]]<s&&siz[c[k][1]]+cnt[k]>=s)return val[k];
        if(siz[c[k][1]]>=s)return query(c[k][1],s);
        else return query(c[k][0],s-siz[c[k][1]]-cnt[k]);//
    }
    int main()
    {
        scanf("%d%lld",&n,&lm);char ch;ll tp;
        while(n--)
        {
            cin>>ch;scanf("%lld",&tp);
            if(ch=='I')
            {
                if(tp-fx<lm)continue;
    //          else insert(rt,0,tp-fx);
                else insert(tp-fx);
            }
            else if(ch=='A')fx+=tp,lm-=tp;
            else if(ch=='S')
            {
                fx-=tp;lm+=tp;
    //          insert(rt,0,lm);
                insert(lm);
                ans+=del(rt,0)-1;
            }
            else {
                if(tp>siz[rt])printf("-1
    ");
                else printf("%lld
    ",query(rt,tp)+fx);
            }
        }
        printf("%d",ans);
        return 0;
    }
    View Code

    可以非递归地 insert。

    这两个的del方式不同。

  • 相关阅读:
    overflow妙用--去除默认滚动条,内容仍可滚动
    call()与构造函数的运用
    this与super
    构造方法
    多态
    抽象类与接口
    面向对象的基本特征
    类与对象
    面向过程与面向对象
    java自动拆装箱
  • 原文地址:https://www.cnblogs.com/Narh/p/9174031.html
Copyright © 2020-2023  润新知