问小于n的数里n/phi(n)最大的数是多少。
由欧拉函数的性质可得n/phi(n)=n/(n*(1-1/p1)*(1-1/p2)...*(1-1/pn))=1/((1-1/p1)*(1-1/p2)...*(1-1/pn)),其中p1~pn为n的质因数。
可见n的质因数越多,n/phi(n)的值越大,所以令n为连续素数的乘积即可。
#include <string.h> #include <stdio.h> struct bign{ int s[205],len; bign(){memset(s,0,sizeof s);len=1;} bign(char *str){*this=str;} bign(int str){*this=str;} bign operator =(const char *str){ len=strlen(str); for(int i=0;i<len;i++)s[len-i-1]=str[i]-'0'; return *this; } bign operator =(const int ss){ char str[205]; sprintf(str,"%d",ss); return *this=str; } bign operator *(const bign& b)const{ bign c;c.len=len+b.len; for(int i=0;i<len;i++){ for(int j=0;j<b.len;j++){ c.s[i+j]+=s[i]*b.s[j]; if(c.s[i+j]>10000){ c.s[i+j+1]+=c.s[i+j]/10000; c.s[i+j]%=10000; } } } for(int i=0;i<c.len;i++){ c.s[i+1]+=c.s[i]/10; c.s[i]%=10; } while(c.len>1&&c.s[c.len-1]==0)c.len--; return c; } bool operator <(const bign &b)const{ if(len!=b.len)return len<b.len; for(int i=len-1;i>=0;i--){ if(s[i]==b.s[i])continue; return s[i]<b.s[i]; } return 0; } void print(){ for(int i=len-1;i>=0;i--)printf("%d",s[i]);printf("\n"); } }b[100],tmp; int p[255]; int ispri(int x){ for(int i=2;i*i<=x;i++) if(x%i==0)return 0; return 1; } void init(){ b[0]=2; for(int i=3,prs=0;i<252;i++){ if(ispri(i)){ p[prs++]=i; bign tmp=p[prs-1]; b[prs]=b[prs-1]*tmp; } } } int cas; char line[205]; int main(){ //freopen("test.in","r",stdin); init(); scanf("%d",&cas); while(cas--){ scanf("%s",line); bign a=line; for(int i=0;;i++){ if(a<b[i]){ b[i-1].print(); break; } } } return 0; }