poj 1442

来源:互联网 发布:淘宝联盟鹊桥怎么用 编辑:程序博客网 时间:2024/06/06 02:22

    题目意思是有一系列数字输入,问在输入到第u个数时,排在以访问次数x为名次的第x小的数。(可能有点误差,很早就做过了,现在有点偷懒不想看题~)

    网上主流的做法是用STL的优先队列做的,我这里有点不同,是用平衡树做的,且是SBT,有关SBT的详细说明请看Winter Club2007 陈启峰的论文Sized Balanced Tree。

 

     以下是代码;

 

  1. #include "stdio.h"#include "string.h"#include "stdlib.h"const int N=50005;const int M=40000;
  2. struct Node{int num;int size;struct Node *l,*r;}*root,tree[M];int a[M],u[M];int tot;int m,n;int it;
  3. void init(){tot=0;it=0;root=NULL;}
  4. int ls(Node *p){return p->l?p->l->size:0;}
  5. int rs(Node *p){return p->r?p->r->size:0;}
  6. void rotate_left(Node* &p){Node *q=p->r;p->r=q->l;q->l=p;q->size=p->size;p->size=ls(p)+rs(p)+1;p=q;}
  7. void rotate_right(Node* &p){Node *q=p->l;p->l=q->r;q->r=p;q->size=p->size;p->size=ls(p)+rs(p)+1;p=q;}
  8. void maintain(Node* &p,bool flag){if(flag){if(p->r && p->r->r && p->r->r->size>ls(p)) rotate_left(p);else if(p->r && p->r->l && p->r->l->size>ls(p)){rotate_right(p->r);rotate_left(p);}}else{if(p->l && p->l->l && p->l->l->size>rs(p)) rotate_right(p);else if(p->l && p->l->r && p->l->r->size>rs(p)){rotate_left(p->l);rotate_right(p);}}}
  9. void insert(int x,Node* &p){if(!p){p=&tree[tot++];p->l=NULL;p->r=NULL;p->size=1;p->num=x;}else{p->size++;if(p->num>x) insert(x,p->l);else insert(x,p->r);maintain(p,x>=p->num);}}
  10. int getkth(int k,Node *p){if(k<=0 || k>p->size) return 0;int lc=ls(p);if(k==lc+1) return p->num;else if(k<=lc) return getkth(k,p->l);else return getkth(k-1-lc,p->r);}int main(){while(scanf("%d%d",&m,&n)==2){init();int i,j;for(i=1;i<=m;i++)scanf("%d",&a[i]);for(i=1;i<=n;i++)scanf("%d",&u[i]);int t=1;for(i=1;i<=m;i++){if(tot!=u[t]){insert(a[i],root);}else{it++;printf("%d/n",getkth(it,root));t++;i--;}}while(t<=n){it++;printf("%d/n",getkth(it,root));t++;}}return 0;}

原创粉丝点击