题意:
定义质因数只为2,3,5,7为丑数...问第n大丑数是什么(1<=n<=5842)
题解:
由于大的数乘以2,3,5,7都不可能得到比其小的数...所以用一个总能保持有序的数据结构维护答案...初始为1..然后依次选出当前最小...乘以2,3,5,7后放入..
更新Treap模板....加了个找一个数字是否在treap中的方法...同时将treap写为一个类...
一个个做实在超时...就在线打表了.....
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<time.h> #include<set> #include<map> #include<math.h> #include<queue> #define MAXN 10005 #define MAXM 805 #define oo 1<<30 #define ll long long using namespace std; int a[4]={2,3,5,7}; ll ans[MAXN]; class treap { private: struct node { int l,r,fix,size; ll key; }h[MAXN]; int root,num; void rot_l(int &x) { int R=h[x].r,L=h[x].l; h[x].size=h[x].size-h[R].size+h[h[R].l].size; h[R].size+=h[L].size+1; h[x].r=h[R].l,h[R].l=x; x=R; } void rot_r(int &x) { int L=h[x].l,R=h[x].r; h[x].size=h[x].size-h[L].size+h[h[L].r].size; h[L].size+=h[R].size+1; h[x].l=h[L].r,h[L].r=x; x=L; } bool insert(int &k,ll key) { if (!k) { k=++num; h[k].l=h[k].r=0,h[k].size=1; h[k].key=key,h[k].fix=rand(); return true; } if (h[k].key==key) return false; if (h[k].key>key) { if (!insert(h[k].l,key)) return false; h[k].size++; if (h[h[k].l].fix>h[k].fix) rot_r(k); return true; }else { if (!insert(h[k].r,key)) return false; h[k].size++; if (h[h[k].r].fix>h[k].fix) rot_l(k); return true; } } bool del(int &k,ll key) { if (!k) return false; if (h[k].key>key) { if (!del(h[k].l,key)) return false; h[k].size--; } else if (h[k].key<key) { if (!del(h[k].r,key)) return false; h[k].size--; } else { if (!h[k].l && !h[k].r) k=0; else if (!h[k].l) k=h[k].r; else if (!h[k].r) k=h[k].l; else { if (h[h[k].l].fix<h[h[k].r].fix) { rot_l(k); if (!del(h[k].l,key)) return false; h[k].size--; } else { rot_r(k); if (!del(h[k].r,key)) return false; h[k].size--; } } } return true; } public: void clear() { srand((int)time(0)),num=root=0; } void push(ll key) { insert(root,key); } bool find(ll key) { int k=root; while (k) { if (h[k].key==key) return true; if (h[k].key>key) k=h[k].l; else k=h[k].r; } return false; } int count(int key) { int g=0,k=root; while (k) { if (h[k].key>key) k=h[k].l; else g+=h[h[k].l].size+1,k=h[k].r; } return g; } ll k_th(int kth) { int g=0,k=root; if (h[root].size<kth) return -1; while (h[h[k].l].size+g+1!=kth) { if (h[h[k].l].size+g+1>=kth) k=h[k].l; else g+=h[h[k].l].size+1,k=h[k].r; } return h[k].key; } void pop(ll key) { del(root,key); } }T; int main() { int k,i,num; ll h,p; freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); T.clear(); T.push(1),num=0; while (num<5842) { h=T.k_th(1); ans[++num]=h; for (i=0;i<4;i++) { p=h*a[i]; if (T.find(p)) continue; T.push(p); } T.pop(h); } while (scanf("%d",&k)) { if (k==0) break; printf("The %d",k); if (k%100>=11 && k%100<=13) printf("th"); else if (k%10==1) printf("st"); else if (k%10==2) printf("nd"); else if (k%10==3) printf("rd"); else printf("th"); printf(" humble number is %I64d.\n",ans[k]); } return 0; }