题意:

              定义质因数只为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;
}