POJ 1442 平衡树Treap模板

点击打开链接

题意:输入m个数,询问n个数,第一个数如果是3,就输出在m的第三个数输入完成后第1大的数,第二个就输出第二大的数,但前提都是在输入完U[i]个数后

思路:用平衡树Treap进行插入和查询第K大的数,模版题

[html]  view plain  copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <iostream>  
  5. #include <algorithm>  
  6. using namespace std;  
  7. typedef long long ll;  
  8. const int inf=0x3f3f3f3f;  
  9. const int maxn=100010;  
  10. class Treap{  
  11.     public:  
  12. struct Treap_Node{  
  13.     Treap_Node *left,*right;  
  14.     int value,fix,weight,size;//fix为修正值,是随机产生的,保证二叉树不会退化的重要环节,wweight为权值,size为子树大小  
  15. }*root,*null;  
  16. Treap(){  
  17.     null=new struct Treap_Node;  
  18.     null->size=0;  
  19.     null->weight=0;  
  20.     null->value=inf;  
  21.     null->left=null;  
  22.     null->right=null;  
  23.     null->fix=inf;  
  24.     root=null;  
  25. }  
  26. void Treap_Print(Treap_Node *P){//从小到大输出  
  27.     if(P!=null){  
  28.         Treap_Print(P->left);  
  29.         printf("%d\n",P->value);  
  30.         Treap_Print(P->right);  
  31.     }  
  32. }  
  33. void Treap_Left_Rotate(Treap_Node *&a){//左旋之后仍不改变二叉树性质  
  34.     Treap_Node *b=a->right;  
  35.     a->right=b->left;  
  36.     b->left=a;  
  37.     b->size=a->size;  
  38.     a->size=a->left->size+a->right->size+a->weight;  
  39.     a=b;  
  40. }  
  41. void Treap_Right_Rotate(Treap_Node *&a){//右旋之后仍不改变二叉树性质  
  42.     Treap_Node *b=a->left;  
  43.     a->left=b->right;  
  44.     b->right=a;  
  45.     b->size=a->size;  
  46.     a->size=a->left->size+a->right->size+a->weight;  
  47.     a=b;  
  48. }  
  49. int Treap_Find(Treap_Node *P,int value){//查找有没有value这个数  
  50.     if(P==null) return 0;  
  51.     if(P->value==value) return 1;  
  52.     else if(value<P->value) return Treap_Find(P->left,value);  
  53.     else return Treap_Find(P->right,value);  
  54. }  
  55. void Treap_Insert(Treap_Node *&P,int value){//插入一个数  
  56.     if(P==null){  
  57.         P=new Treap_Node;  
  58.         P->left=P->right=null;//左右儿子均为空  
  59.         P->value=value;  
  60.         P->fix=rand();  
  61.         P->weight=1;  
  62.         P->size=1;  
  63.     }else if(value==P->value){  
  64.         P->weight++;  
  65.     }  
  66.     else if(value<P->value){  
  67.         Treap_Insert(P->left,value);  
  68.         if(P->left->fix<P->fix)  
  69.             Treap_Right_Rotate(P);  
  70.     }else{  
  71.         Treap_Insert(P->right,value);  
  72.         if(P->right->fix<P->fix)  
  73.             Treap_Left_Rotate(P);  
  74.     }  
  75.     P->size=P->left->size+P->right->size+P->weight;  
  76. }  
  77. void Treap_Delete(Treap_Node *&P,int value){//删除一个数  
  78.     if(P==null) return ;  
  79.     if(value<P->value) Treap_Delete(P->left,value);  
  80.     else if(value>P->value) Treap_Delete(P->right,value);  
  81.     else if(P->weight>1) P->weight--;  
  82.     else if((P->left==NULL)&&(P->right==NULL)){  
  83.         delete P;  
  84.         P=NULL;  
  85.     }else{  
  86.         if(P->left->fix<P->right->fix) Treap_Left_Rotate(P);  
  87.         else Treap_Right_Rotate(P);  
  88.         Treap_Delete(P,value);  
  89.     }  
  90.     P->size=P->left->size+P->right->size+P->weight;  
  91. }  
  92. int Treap_pred(Treap_Node *P,int value,Treap_Node *optimal){//前驱  
  93.     if(P==null||value==P->value) return optimal->value;  
  94.     if(P->value<value) return Treap_pred(P->right,value,P);  
  95.     else return Treap_pred(P->left,value,optimal);  
  96. }  
  97. int Treap_succ(Treap_Node *P,int value,Treap_Node *optimal){//后继  
  98.     if(P==null||value==P->value) return optimal->value;  
  99.     if(P->value>value) return Treap_succ(P->left,value,P);  
  100.     else return Treap_succ(P->right,value,optimal);  
  101. }  
  102. int Treap_Findkth(Treap_Node *P,int k){//求第K大的数  
  103.     if(P==null) return 0;  
  104.     int t=P->left->size;  
  105.     if(k<t+1) return Treap_Findkth(P->left,k);  
  106.     else if(k>t+P->weight) return Treap_Findkth(P->right,k-(t+P->weight));  
  107.     else return P->value;  
  108. }  
  109. int Treap_Rank(Treap_Node *P,int value,int cur){//求这个数的排名  
  110.     int t=P->left->size;  
  111.     if(value==P->value) return t+cur+1;  
  112.     else if(value<P->value) return Treap_Rank(P->left,value,cur);  
  113.     else return Treap_Rank(P->right,value,t+cur+P->weight);  
  114. }  
  115. void Treap_erase(Treap_Node *&P) {//将树清空  
  116.         if(P->left!=null)  
  117.             Treap_erase(P->left);  
  118.         if(P->right!=null)  
  119.             Treap_erase(P->right);  
  120.         delete P;  
  121. }  
  122. };  
  123. int num[30010],num1[50010];  
  124. int main(){  
  125.     int n,a,b,m;  
  126.     while(scanf("%d%d",&n,&m)!=-1){  
  127.         Treap tree;  
  128.         for(int i=1;i<=n;i++) scanf("%d",&num[i]);  
  129.         int t=1,k=1;  
  130.         for(int i=1;i<=m;i++) scanf("%d",&num1[i]);  
  131.         while(t<=m){  
  132.             while(k<=num1[t]){  
  133.                 tree.Treap_Insert(tree.root,num[k]);  
  134.                 k++;  
  135.             }  
  136.             int ans=tree.Treap_Findkth(tree.root,t++);  
  137.             printf("%d\n",ans);  
  138.         }  
  139.     }  
  140.     return 0;  
  141. }  
[html]  view plain  copy
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <iostream>  
  5. #include <algorithm>  
  6. using namespace std;  
  7. typedef long long ll;  
  8. typedef unsigned long long ull;  
  9. const int inf=0x3f3f3f3f;  
  10. const ll INF=0x3f3f3f3f3f3f3f3fll;  
  11. const int maxn=15010;  
  12. struct Node{  
  13.     Node *ch[2];  
  14.     int r,v,s;  
  15.     Node(int v):v(v){ch[0]=ch[1]=NULL;r=rand();s=1;}  
  16.     int cmp(int x){  
  17.         if(x==v) return -1;  
  18.         return x<v? 0:1;  
  19.     }  
  20.     void maintain(){  
  21.         s=1;  
  22.         if(ch[0]!=NULL) s+=ch[0]->s;  
  23.         if(ch[1]!=NULL) s+=ch[1]->s;  
  24.     }  
  25. };  
  26. void Rotate(Node* &o,int d){  
  27.     Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;  
  28.     o->maintain();k->maintain();o=k;  
  29. }  
  30. void Insert(Node* &o,int x){  
  31.     if(o==NULL) o=new Node(x);  
  32.     else{  
  33.         int d=x<(o->v)? 0:1;  
  34.         Insert(o->ch[d],x);  
  35.         if(o->ch[d]->r>o->r) Rotate(o,d^1);  
  36.     }  
  37.     o->maintain();  
  38. }  
  39. void Remove(Node* &o,int x){  
  40.     int d=o->cmp(x);  
  41.     if(d==-1){  
  42.         Node* u=o;  
  43.         if(o->ch[0]!=NULL&&o->ch[1]!=NULL){  
  44.             int d2=(o->ch[0]->r>o->ch[1]->r?1:0);  
  45.             Rotate(o,d2);Remove(o->ch[d2],x);  
  46.         }else{  
  47.             if(o->ch[0]==NULL) o=o->ch[1];  
  48.             else o=o->ch[0];  
  49.             delete u;  
  50.         }  
  51.     }else Remove(o->ch[d],x);  
  52.     if(o!=NULL) o->maintain();  
  53. }  
  54. int Kth(Node* &o,int k){//第K大的值  
  55.     if(o==NULL||k<=0||k>o->s) return 0;  
  56.     int s=(o->ch[0]==NULL?0:o->ch[0]->s);  
  57.     if(k==s+1) return o->v;  
  58.     else if(k<=s) return Kth(o->ch[0],k);  
  59.     else return Kth(o->ch[1],k-s-1);  
  60. }  
  61. int Rank(Node* &o,int x){//x的排名  
  62.     if(o==NULL) return -1;//未找到  
  63.     int num=o->ch[0]==NULL?0:o->ch[0]->s;  
  64.     if(x==o->v) return num+1;  
  65.     else if(x<o->v) return Rank(o->ch[0],x);  
  66.     else return Rank(o->ch[1],x)+num+1;  
  67. }  
  68. void deletetree(Node* &o){  
  69.     if(o->ch[0]!=NULL) deletetree(o->ch[0]);  
  70.     if(o->ch[1]!=NULL) deletetree(o->ch[1]);  
  71.     delete o;o=NULL;  
  72. }  
  73. int num[30010],num1[50010];  
  74. int main(){  
  75.     int n,m,a,b;  
  76.     while(scanf("%d%d",&n,&m)!=-1){  
  77.         Node* root=NULL;  
  78.         for(int i=1;i<=n;i++) scanf("%d",&num[i]);  
  79.         for(int i=1;i<=m;i++) scanf("%d",&num1[i]);  
  80.         int t=1,k=1;  
  81.         while(t<=m){  
  82.             while(k<=num1[t]){  
  83.                 Insert(root,num[k]);  
  84.                 k++;  
  85.             }  
  86.             int ans=Kth(root,t++);  
  87.             printf("%d\n",ans);  
  88.         }  
  89.         deletetree(root);  
  90.     }  
  91.     return 0;  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值