JZOJ 5791. 【NOIP2008模拟】阶乘
题解很完善,直接上代码!
1 #include<iostream> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstdio> 6 #define int long long 7 using namespace std; 8 const int MAXN=100005;int a[MAXN]; 9 int p[MAXN],n,k,m,cnt=0,mx=-0x3fffffff;bool v[MAXN]; 10 void divide(int x){ 11 int s=x; 12 for(int i=2;i*i<=x;i++){ 13 if(s%i) continue; 14 v[i]=1;mx=max(mx,i); 15 while(s%i==0) p[i]++,s/=i; 16 } if(s>1) v[s]=1,p[s]++,mx=max(mx,s); 17 } 18 int fpow(int x,int k){ 19 int r=1; 20 while(k){ 21 if(k&1) r*=x; 22 x*=x;k>>=1; 23 } return r; 24 } 25 int get(int fac,int num){ 26 int tot=0; 27 for(int i=1;;i++) 28 if(fac>fpow(num,i)) 29 tot+=fac/fpow(num,i);else break; 30 return tot; 31 } 32 bool pd(int fac){ 33 for(int i=1;i<=mx;i++){ 34 if(!v[i]) continue; 35 if(get(fac,i)<p[i]) return 0; 36 } return 1; 37 } 38 int bsearch(){ 39 int l=0,r=1000000000,mid,ans=0; 40 while(l<=r){ 41 mid=(l+r)>>1; 42 if(pd(mid)) ans=mid,r=mid-1; 43 else l=mid+1; 44 } return ans; 45 } 46 signed main(){ 47 freopen("factorial.in","r",stdin); 48 freopen("factorial.out","w",stdout); 49 scanf("%lld",&n); 50 for(int i=1;i<=n;i++) 51 scanf("%lld",&a[i]),divide(a[i]); 52 printf("%lld\n",bsearch()); 53 }