先解释一下SAPGAP=Super AntiPrime, Greatest AntiPrime(真不是网络流),于是你就应该知道本题是一个关于反质数(Antiprime)的问题。下面给出反质数的定义:
将一个正整数i的约数个数记为g(i),如g(1)=1,g(2)=2,g(6)=4。
如果对于一个正整数k,对于任意正整数i<k,均有g(k)>g(i),则k被称为反质数。
比如说1,2,4,6,12就是前5个反质数。
现在给定一个N,求N以内最大的反质数。
你一定会认为这道题很简单,你曾经做过好多遍(它就是许许多多竞赛的原题呀),但是这次真的不一样。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
const int bi=1e4,MN=30;
char c[100000];
int pr[62]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293};
struct big{
int a[MN];
inline big(){
memset(a,0,sizeof(a));
a[0]=1;
}
inline void read(){
register int i,j;
scanf("%s",c);
a[0]=(strlen(c)+3)/4;
for (i=0;i<strlen(c);i++) j=(strlen(c)-i+3)/4,a[j]=a[j]*10+c[i]-48;
}
inline void pr(){
register int i;
printf("%d",a[a[0]]);
for (i=a[0]-1;i;i--) printf("%04d",a[i]);
}
inline big operator =(int x){
if (x==0){
memset(a,0,sizeof(a));
a[0]=1;
}
a[0]=0;
while (x){
a[0]++;
a[a[0]]=x%bi;
x/=bi;
}
if (!a[0]) a[0]=1;
}
inline big(int x){
*this=x;
}
inline void gl(){
while(!a[a[0]]&&a[0]>1) a[0]--;
}
inline big operator =(big x){
register int i;
a[0]=x.a[0];
for (i=1;i<=a[0];i++) a[i]=x.a[i];
}
inline bool operator >(big y){
if (a[0]!=y.a[0]) return a[0]>y.a[0];
for (register int i=a[0];i;i--){
if (a[i]!=y.a[i]) return a[i]>y.a[i];
}
return 0;
}
inline bool operator >=(const big y){
if (a[0]!=y.a[0]) return a[0]>y.a[0];
for (register int i=a[0];i;i--){
if (a[i]!=y.a[i]) return a[i]>y.a[i];
}
return 1;
}
inline bool operator <(big y){
if (a[0]!=y.a[0]) return a[0]<y.a[0];
for (register int i=a[0];i;i--){
if (a[i]!=y.a[i]) return a[i]<y.a[i];
}
return 0;
}
inline bool operator <=(big y){
if (a[0]!=y.a[0]) return a[0]<y.a[0];
for (register int i=a[0];i;i--){
if (a[i]!=y.a[i]) return a[i]<y.a[i];
}
return 1;
}
inline bool operator ==(big y){
if (a[0]!=y.a[0]) return 0;
for (register int i=a[0];i;i--){
if (a[i]!=y.a[i]) return 0;
}
return 1;
}
inline bool operator !=(big y){
return !(*this==y);
}
inline bool operator ==(int y){
big x=y;
return *this==x;
}
inline bool operator !=(int y){
return !(*this==y);
}
inline void swap(big &a,big &b){
big x=a;a=b;b=x;
}
inline big operator +(big x){
big r;
if (a[0]<x.a[0]) r.a[0]=x.a[0];else r.a[0]=a[0];
for (register int i=1;i<=r.a[0];i++) r.a[i]=a[i]+x.a[i];
for (register int i=1;i<=r.a[0];i++)
if (r.a[i]>=bi){
r.a[i]-=bi;r.a[i+1]++;
if (i==r.a[0]) r.a[0]++;
}
return r;
}
inline big operator -(big x){
if (*this<x) swap(*this,x);
register int i;
big r;
if (a[0]<x.a[0]) r.a[0]=x.a[0];else r.a[0]=a[0];
for (i=1;i<=r.a[0];i++) r.a[i]=a[i]-x.a[i];
for (i=1;i<=r.a[0];i++)
if (r.a[i]<0){
r.a[i+1]--;r.a[i]+=bi;
}
r.gl();
return r;
}
inline big operator *(big y){
register int i,j;
big r;r.a[0]=a[0]+y.a[0]-1;
for (i=1;i<=a[0];i++)
for (j=1;j<=y.a[0];j++) r.a[i+j-1]+=a[i]*y.a[j];
for (i=0;i<=r.a[0];i++)
if (r.a[i]>=bi){
r.a[i+1]+=r.a[i]/bi;
r.a[i]%=bi;
if (i==r.a[0]) r.a[0]++;
}
return r;
}
inline big half(){
register int i,j;
for (i=a[0];i>1;i--) a[i-1]+=(a[i]%2)*bi,a[i]/=2;
a[1]/=2;
gl();
return *this;
}
inline big operator /(big y){
register int i,j;
big r,l,mid,rq=*this;
r.a[0]=rq.a[0]+1;r.a[r.a[0]]=1;
while(r>l){
mid=(l+r+big(1)).half();
if (mid*y<=rq) l=mid;else r=mid-big(1);
}
return l;
}
inline big operator %(big y){
register int i,j;
big rq=*this;
return rq-(rq/y*y);
}
}n,ans;
long long cu;
void dfs(int pos,int p,big sum,long long su){
if (pos==1&&p>9) p=9;else
if (pos==2&&p>5) p=5;else
if (pos==3&&p>4) p=4;else
if (pos==4&&p>2) p=2;else
if (pos==9&&p>1) p=1;
if (pos>61||sum>n) return;
if ((su>cu)||(sum<ans&&cu==su)) cu=su,ans=sum;
for (register int i=1;i<=p;i++){
sum=sum*big(pr[pos]);
if (sum>n) return;
dfs(pos+1,i,sum,su*(i+1));
}
}
int main(){
n.read();
dfs(0,13,big(1),1);
ans.pr();
}