Treap小结

来源:互联网 发布:java怎么写入csv文件 编辑:程序博客网 时间:2024/05/18 11:50

Treap(Tree+Heap)---是一种通过 rand() 来随机生成数字作为修正值来调整的平衡树。

基本操作:

1.旋转。

2.插入(合并重复的),删除(懒惰删除)。

3.查最值,求第k小,求排名。

4.中序遍历就是从小到大的。

5.维护附加关键字.

1.求第k小:

POJ1442

//123211991442Accepted976K204MSC++2080B2013-11-22 20:33:35静态//123212161442Accepted1804K329MSC++2125B2013-11-22 20:39:40动态#include <iostream>#include<cstdio>#include<ctime>#include<cstring>#include<cstdlib>using namespace std;#define MAX 30005int a[MAX];int u[MAX];int tot;class Node{public:    int vol,fix;    int size;    Node *left;    Node *right;    int lsize(){return left?left->size:0;}    int rsize(){return right?right->size:0;}}*root;//space[MAX]void left_rotate(Node *&a){    Node *b=a->right;    a->right=b->left;    b->left=a;    a=b;    b=a->left;    b->size=b->lsize()+b->rsize()+1;    a->size=a->lsize()+a->rsize()+1;}void right_rotate(Node *&a){    Node *b=a->left;    a->left=b->right;    b->right=a;    a=b;    b=a->right;    b->size=b->lsize()+b->rsize()+1;    a->size=a->lsize()+a->rsize()+1;}void insert(Node*&p,int vol){    if(!p)    {        p=new Node();        //p=&space[tot++];  //静态        p->fix=rand();        p->vol=vol;        p->size=1;    }    else if(vol<=p->vol)    {        insert(p->left,vol);        p->size++;        if(p->left->fix < p->fix)            right_rotate(p);    }    else    {        insert(p->right,vol);        p->size++;        if(p->right->fix < p->fix)            left_rotate(p);    }}int get_kth(Node *&p,int k){    int key=p->lsize()+1;    if(k < key)        return get_kth(p->left,k);    else if(k > key)        return get_kth(p->right,k-key);    else        return p->vol;}void init(){        root=NULL;        //memset(space,0,sizeof(space));静态        //tot=1;}int main(){    srand(time(0));    int n,m;    while(~scanf("%d%d",&m,&n))    {        for(int i=1;i<=m;i++) scanf("%d",&a[i]);        for(int i=1;i<=n;i++) scanf("%d",&u[i]);        int j=1;        init();        for(int i=1;i<=m;i++)        {            insert(root,a[i]);            while(j<=n&&i==u[j])            {                printf("%d\n",get_kth(root,j));                j++;            }            if(j>n) break;        }    }    return 0;}

2.动态求最值

//123217283481Accepted212K282MSC++1857B2013-11-22 22:26:19动态#include <iostream>#include<cstdlib>#include<ctime>#include<cstdio>#include<cstring>using namespace std;//#define MAX 10000005class Node{public:    int vol,fix,cus;    Node* left;    Node* right;}*root;//,space[MAX]  int tot=1;void r_rotate(Node*&a){    Node*b=a->left;    a->left=b->right;    b->right=a;    a=b;    b=a->right;}void l_rotate(Node*&a){    Node*b=a->right;    a->right=b->left;    b->left=a;    a=b;    b=a->left;}void insert(Node*&p,int cus,int vol){    if(!p)    {        p=new Node();        //p=&space[tot++];        p->fix=rand();        p->vol=vol;        p->cus=cus;    }    else if(p->vol >= vol)    {        insert(p->left,cus,vol);        if(p->left->fix < p->fix)            r_rotate(p);    }    else    {        insert(p->right,cus,vol);        if(p->right->fix < p->fix)            l_rotate(p);    }}int Min(Node*&p){    if(!p)return 0;    if(!p->left)    {        Node*t=p;        int ans=p->cus;        p=p->right;        delete t;        return ans;    }    else return Min(p->left);}int Max(Node*&p){    if(!p)return 0;    if(!p->right)    {        Node*t=p;        int ans=p->cus;        p=p->left;        delete t;        return ans;    }    else return Max(p->right);}int main(){    srand(time(0));    int a;    while(~scanf("%d",&a)&&a)    {        if(a==1)        {            int b,c;            scanf("%d%d",&b,&c);            insert(root,b,c);        }        else if(a==3)        {            printf("%d\n",Min(root));        }        else        {            printf("%d\n",Max(root));        }    }    return 0;}

3.区间第k小:

//123298082761Accepted3500K1844MSC++3889B2013-11-25 21:28:45静态//123298362761Accepted3900K3922MSC++3962B2013-11-25 21:34:10动态#include <iostream>#include<cstdio>#include<ctime>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;#define MAX 2000005int dog[MAX];int ans[MAX];class Interval{public:    int s,e,k;    int id;    bool operator<(const Interval a) const    {        return s<a.s;    }}qu[MAX];class Node{public:    int vol,fix,size;    Node*left;    Node*right;    int lsize(){return left?left->size:0;}    int rsize(){return right?right->size:0;}}*root,space[MAX];int tot;void r_rotate(Node*&a){    Node*b=a->left;    a->left=b->right;    b->right=a;    a=b;    b=a->right;    b->size=b->lsize()+b->rsize()+1;/**RE在这里,不要把求size顺序搞反了*/    a->size=a->lsize()+a->rsize()+1;}void l_rotate(Node*&a){    Node*b=a->right;    a->right=b->left;    b->left=a;    a=b;    b=a->left;    b->size=b->lsize()+b->rsize()+1;    a->size=a->lsize()+a->rsize()+1;}void insert(Node*&p,int vol){    if(!p)    {        p=&space[tot++];        //p=new Node();        p->left=NULL;        p->right=NULL;        p->fix=rand();        p->vol=vol;        p->size=1;    }    else if(p->vol > vol)    {        p->size++;        insert(p->left,vol);        if(p->left->fix < p->fix)            r_rotate(p);    }    else    {        p->size++;        insert(p->right,vol);        if(p->right->fix < p->fix)            l_rotate(p);    }}void del(Node*&p,int key){    if(!p) return ;    p->size--;  /**注意size的减减**/    if(key==p->vol)    {        if(!p->left || !p->right)        {            //Node *t=p;            if(!p->left)                p=p->right;            else                p=p->left;            //delete t;        }        else        {            if(p->right->fix < p->left->fix)            {                l_rotate(p);                p->size--;/**注意size的减减**/                del(p->left,key);            }            else            {                r_rotate(p);                p->size--;/**注意size的减减**/                del(p->right,key);            }        }    }    else if(key < p->vol)        del(p->left,key);    else        del(p->right,key);}int find_kth(Node*&p,int k){    int sum=p->lsize()+1;    if(k < sum)    {        return find_kth(p->left,k);    }    else if(k>sum)    {        return find_kth(p->right,k-sum);    }    else    {        return p->vol;    }}int solve(Interval t1,Interval t2){    for(int i=t1.s;i<=min(t2.s-1,t1.e);i++)        del(root,dog[i]);    if(t1.e > t2.e)    {        for(int i=t2.e+1;i<=t1.e;i++)            del(root,dog[i]);    }    for(int i=max(t1.e+1,t2.s);i<=t2.e;i++)        insert(root,dog[i]);    return find_kth(root,t2.k);}int main(){    srand(time(0));    //int T;    //scanf("%d",&T);    int n,m;    while(~scanf("%d%d",&n,&m))    {        root=NULL;        tot=1;        memset(space,NULL,sizeof(space));        for(int i=1;i<=n;i++)            scanf("%d",&dog[i]);        for(int i=1;i<=m;i++)        {            scanf("%d%d%d",&qu[i].s,&qu[i].e,&qu[i].k);            if(qu[i].s > qu[i].e) swap(qu[i].s,qu[i].e);            qu[i].id=i;        }        sort(qu+1,qu+1+m);        for(int i=qu[1].s;i<=qu[1].e;i++)            insert(root,dog[i]);        ans[qu[1].id]=find_kth(root,qu[1].k);        for(int i=2;i<=m;i++)        {            ans[qu[i].id]=solve(qu[i-1],qu[i]);        }        for(int i=1;i<=m;i++)        printf("%d\n",ans[i]);    }    return 0;}




原创粉丝点击