poj 1442 名次树
这回要求的是第k小的元素,
参考了ljl大神的模板,orz
1 //insert 插入 2 //remove 删除 3 //_find 查找 4 //kth 返回root为根的树中第k小的元素 5 //treap插入、删除、查询时间复杂度均为O(logn) 6 #include <iostream> 7 #include <cstring> 8 #include <cstdlib> 9 #include <ctime> 10 #include <cstdio> 11 using namespace std; 12 int a[300010],n,m; 13 struct Node 14 { 15 Node *ch[2]; 16 int r,v,s; 17 Node(int v):v(v) 18 {s=1;ch[0]=ch[1]=NULL;r=rand();} 19 int cmp(int x) const{ 20 if(x==v)return(-1); 21 return (x<v)?(0):(1); 22 } 23 void maintain(){ 24 s=1; 25 if(ch[0]!=NULL)s+=ch[0]->s; 26 if(ch[1]!=NULL)s+=ch[1]->s; 27 } 28 }; 29 void rotate(Node* &o,int d) 30 { 31 Node* k=o->ch[d^1]; 32 o->ch[d^1]=k->ch[d]; 33 k->ch[d]=o; 34 o->maintain(); 35 k->maintain(); 36 o=k; 37 } 38 void insert(Node* &o,int x) 39 { 40 if(o==NULL) o=new Node(x); 41 else { 42 int d=(x<o->v)?0:1; 43 insert(o->ch[d],x); 44 if((o->r)<(o->ch[d]->r)) 45 rotate(o,d^1); 46 } 47 o->maintain(); 48 } 49 void remove(Node* &o,int x) 50 { 51 int d=o->cmp(x); 52 if(d==-1){ 53 Node* u=o; 54 if(o->ch[0]==NULL){o=o->ch[1];delete u;}else 55 if(o->ch[1]==NULL){o=o->ch[0];delete u;}else { 56 int c=(o->ch[0])>(o->ch[1])?(1):(0); 57 rotate(o,c); 58 remove(o->ch[c],x); 59 } 60 } 61 else remove(o->ch[d],x); 62 if(o!=NULL) o->maintain(); 63 } 64 int find(Node* &o,int x) 65 { 66 while(o!=NULL){ 67 int d=o->cmp(x); 68 if(d==-1) 69 return 1; 70 else 71 o=o->ch[d]; 72 } 73 return 0; 74 } 75 int kth(Node* o,int k) 76 { 77 while(o!=NULL){ 78 int lchsize=(o->ch[0]!=NULL)? 79 (o->ch[0]->s):0; 80 if(lchsize+1==k) 81 return o->v; 82 else { 83 int d=(lchsize<k); 84 o=o->ch[d]; 85 k-=d*(lchsize+1); 86 } 87 } 88 return 0; 89 } 90 91 int main() 92 { 93 Node* root=NULL; 94 int u,ans,p=0; 95 srand(time(0)); 96 97 cin>>m>>n; 98 for(int i=0;i<m;i++) 99 cin>>a[i]; 100 for(int i=1;i<=n;i++) 101 { 102 cin>>u; 103 while(p<u) 104 insert(root,a[p++]); 105 ans=kth(root,i); 106 cout<<ans<<endl; 107 } 108 return 0; 109 }
posted on 2014-10-28 18:13 Pentium.Labs 阅读(237) 评论(0) 编辑 收藏 举报