Description
先解释一下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以内最大的反质数。
你一定会认为这道题很简单,你曾经做过好多遍(它就是许许多多竞赛的原题呀),但是这次真的不一样。
Input
一个正整数N(1≤N≤10100)。
Output
一个正整数,表示不超过N的最大的反质数。
Sample Input
1000
Sample Output
840
套个高精度模板,然后搜个索,剪个枝就好了……
壮哉我大云神……
#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(); }