POJ 1442-Treap(插入+區間第k大)

還是套板子直接求。


/****************************
* author:crazy_石頭
* date:2014/05/08
* time:313 ms
* algorithm:Treap-求區間第大數
* Pro:POJ 1442
***************************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define INF 1<<29
#define eps 1e-8
#define A system("pause")
#define rep(i,h,n) for(int i=(h);i<=(n);i++)
#define ms(a,b) memset((a),(b),sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define LL long long
#define mod 100000000
const int maxn=100000+5;
const int maxm=100+10;
struct Node
{
    Node* ch[2];//定義左右子樹;
    int r,v;//每個結點的隨機優先級及value;
    int s;//結點總數;
    Node(int v):v(v)
    {
        ch[0]=ch[1]=NULL;
        r=rand();
        s=1;
    }
    bool operator <(const Node& rhs)const
    {
        return rs;
        if(ch[1]!=NULL) s+=ch[1]->s;
    }
};

inline void rotate(Node* &o,int d)//d==0表示左旋,d==1表示右旋;
{
    Node* k=o->ch[d^1];
    o->ch[d^1]=k->ch[d];
    k->ch[d]=o;
    o->maintain();
    k->maintain();
    o=k;
}

inline void insert(Node* &o,int x)//先是普通插入,if(x_vv?0:1);//不要用cmp函數,可能會有相同結點;
        insert(o->ch[d],x);//插入新結點,比較優先級進行旋轉;
        if(o->ch[d]->r>o->r) rotate(o,d^1);
    }
    o->maintain();//維護結點o的信息;
}

inline void remove(Node* &o,int x)
{
    int d=o->cmp(x);
    if(d==-1)
    {
        Node* u=o;
        if(o->ch[0]!=NULL && o->ch[1]!=NULL)
        {
            int d2=(o->ch[0]->r>o->ch[1]->r?1:0);
            rotate(o,d2);
            remove(o->ch[d2],x);
        }
        else
        {
            if(o->ch[0]==NULL) o=o->ch[1];
            else o=o->ch[0];
            delete u;
        }
    }
    else
        remove (o->ch[d],x);
    if(o!=NULL) o->maintain();
}
//查找區間第k大數;
inline int kth(Node* o,int k)
{
    if(o==NULL || k<=0 || k>o->s) return 0;
    int s=(o->ch[0]==NULL? 0:o->ch[0]->s);
    if(k==s+1) return o->v;
    else if(k<=s) return kth(o->ch[0],k);
    else return kth(o->ch[1],k-s-1);
}

int a[maxn],n,m;
int main()
{
    Node* rt=NULL;
    scanf("%d%d",&m,&n);
    rep(i,1,m) scanf("%d",&a[i]);
    int st=1,test;
    rep(i,1,n)
    {
        scanf("%d",&test);
        while(st<=test)
        {
            insert(rt,a[st]);
            st++;
        }
        printf("%d\n",kth(rt,i));
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章