POJ 2761(Treap離線求區間第k大數)

網上有好多解法,我照着LRJ的白書敲了一個板子吧,3907ms過的,這題還可以SBT過,主席樹也是可以過得。劃分樹不知道行不行,反正做法挺多。。T_T。



/****************************
* author:crazy_石頭
* date:2014/05/08
* time:3907 ms
* algorithm:Treap-求區間第大數
* Pro:POJ 2761
***************************/
#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);
}

struct Q
{
    int l,r,k,id;
    bool operator<(const Q& B)const
    {
        return l

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