zoukankan      html  css  js  c++  java
  • POJ 1442 Black Box (堆 || 线段树 || SBT || Splay)

    题目:http://poj.org/problem?id=1442

    简单的插入、查询第k大数的题。这本来应该算一道经典的堆的应用题,结果我用SBT水过去了。。。算了,有机会要用堆实现一下。

     

    SBT 版:

    顺便说下,用cin一次TLE一次1000MS惊现过去,换成scanf 400MS无压力。。。(跟其他人比还是太慢了。。。)

    POJ 1442 SBT
    #include <fstream>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <iomanip>
    #include <iomanip>
    #include <climits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    const int maxn= 100010;
    
    class SBT{
    public:
        void Clear(){
            memset(K,0,sizeof(K));
            memset(L,0,sizeof(L));
            memset(R,0,sizeof(R));
            memset(S,0,sizeof(S));
            RT= SZ= 0;
        }
        void Insert(int key)    {Insert(RT,key);}
        int Delete(int key)     {return Delete(RT,key);}
        int Succ(int key)       {return Succ(RT,key);}
        int Pred(int key)       {return Pred(RT,key);}
        int Rank(int key)       {return Rank(RT,key);}
        int Search(int key)     {return Search(RT,key);}
        int Select(int key)     {return Select(RT,key);}
    
    private:
        int K[maxn];
        int L[maxn];
        int R[maxn];
        int S[maxn];
        int RT, SZ;
        void LeftRotate(int &x){
            int k= R[x];
            R[x]= L[k];
            L[k]=  x;
            S[k]= S[x];
            S[x]= S[L[x]]+S[R[x]]+1;
            x= k;
        }
        void RightRotate(int &x){
            int k= L[x];
            L[x]= R[k];
            R[k]= x;
            S[k]= S[x];
            S[x]= S[L[x]]+S[R[x]]+1;
            x= k;
        }
         void MaintainFat(int &t){
            if (S[L[L[t]]]>S[R[t]]){
                RightRotate(t);
                MaintainFat(R[t]);
                MaintainFat(t);
                return;
            }
            if (S[R[L[t]]]>S[R[t]]){
                LeftRotate(L[t]);
                RightRotate(t);
                MaintainFat(L[t]);
                MaintainFat(R[t]);
                MaintainFat(t);
                return;
            }
            if (S[R[R[t]]]>S[L[t]]){
                LeftRotate(t);
                MaintainFat(L[t]);
                MaintainFat(t);
                return;
            }
            if (S[L[R[t]]]>S[L[t]]){
                RightRotate(R[t]);
                LeftRotate(t);
                MaintainFat(L[t]);
                MaintainFat(R[t]);
                MaintainFat(t);
                return;
            }
    
        }
        void Maintain(int &t, int flag){
            if (!flag){
                if (S[L[L[t]]] >S[R[t]])
                    RightRotate(t);
                else if (S[R[L[t]]] >S[R[t]]){
                    LeftRotate(L[t]);
                    RightRotate(t);
                }
                else
                    return;
            }
            else{
                if (S[R[R[t]]] >S[L[t]])
                    LeftRotate(t);
                else if (S[L[R[t]]] >S[L[t]]){
                    RightRotate(R[t]);
                    LeftRotate(t);
                }
                else
                    return;
            }
            Maintain(L[t], false);
            Maintain(R[t], true);
            Maintain(t, true);
            Maintain(t, false);
        }
        void Insert(int &t, int key){
            if (t==0){
                t= ++SZ;
                K[t]= key;
                S[t]= 1;
                return;
            }
            S[t]++;
            if (key<K[t])
                Insert(L[t],key);
            else
                Insert(R[t],key);
            Maintain(t,key>K[t]);
    
        }
        int Delete(int &t, int key){
            S[t]--;
            if ((key==K[t])||(key<K[t]&&L[t]==0)||(key>K[t]&&R[t]==0)){
                int ret= K[t];
                if (L[t]==0 || R[t]==0)
                    t= L[t]+R[t];       // T change to his Leftson or Rightson
                else
                    K[t]= Delete(L[t], K[t]+1); // Not find then delete the last find Point
                return ret;
            }
            else{
                if (key<K[t])
                    return Delete(L[t],key);
                else
                    return Delete(R[t],key);
            }
    
        }
        int Search(int t, int key){     //return root point
            if (t==0 || key==K[t])
                return t;
            if (key<K[t])
                return Search(L[t],key);
            else
                return Search(R[t],key);
    
        }
        int Select(int t, int k){       // return K-th int tree
            int num= S[L[t]]+1;
            if (k==num)
                return K[t];
            else if (k<num)
                return Select(L[t],k);
            else
                return Select(R[t],k-num);
    
        }
        int Succ(int t, int key){
            if (t==0)
                return key;
            if (key>=K[t])                 //
                return Succ(R[t], key);
            else{
                int r= Succ(L[t], key);
                if (r==key)
                    return K[t];
                else
                    return r;
            }
    
        }
        int Pred(int t, int key){
            if (t==0)
                return key;
            if (key<=K[t])                 //
                return Pred(L[t], key);
            else {
                int r= Pred(R[t], key);
                if (r==key)
                    return K[t];
                else
                    return r;
            }
    
        }
        int Rank(int t, int key){
            if (t==0)
                return 1;
            if (key<=K[t])           //
                return Rank(L[t], key);
            else if (key>K[t])
                return S[L[t]]+1+Rank(R[t],key);
    
        }
    };
    
    int main()
    {
        int a[30005];
        int com[30005];
        memset(com,0,sizeof(com));
    
        SBT sbt;
        int sbtnum=0;
        int n,m;
        scanf("%d%d",&m,&n);
        for (int i=0;i<m;i++)
            scanf("%d",&a[i]);
        for (int i=0;i<n;i++)
        {
            int k;
            scanf("%d",&k);
            com[k]++;
        }
    
        int k=0;
        for (int i=0;i<m;i++)
        {
            sbt.Insert(a[i]);
            sbtnum++;
            while(com[sbtnum])
            {
                com[sbtnum]--;
                k++;
                printf("%d\n",sbt.Select(k));
            }
        }
    
        return 0;
    }

     

    STL priority_queue堆版:

    先占个位^_^~~~

     

    线段树版:

    先占个位^_^~~~

    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    github误fork后删除
    初识javascript
    struts验证框架失效
    Java基础学习1Java标识符及基本类型
    dos 命令行方式下启动和停止MySql服务
    html
    给文本框添加边框的两种方法
    银行家算法
    解决MyEclipse里Tomcat端口被占用而无法启动的情况
    Java近似圆
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/2625181.html
Copyright © 2011-2022 走看看