链接: http://codeforces.com/problemset/problem/300/E
In a far away galaxy there is war again. The treacherous Republic made k precision strikes of power ai on the Empire possessions. To cope with the republican threat, the Supreme Council decided to deal a decisive blow to the enemy forces.
To successfully complete the conflict, the confrontation balance after the blow should be a positive integer. The balance of confrontation is a number that looks like , where p = n! (n is the power of the Imperial strike), . After many years of war the Empire's resources are low. So to reduce the costs, n should be a minimum positive integer that is approved by the commanders.
Help the Empire, find the minimum positive integer n, where the described fraction is a positive integer.
The first line contains integer k (1 ≤ k ≤ 106). The second line contains k integers a1, a2, ..., ak (1 ≤ ai ≤ 107).
Print the minimum positive integer n, needed for the Empire to win.
Please, do not use the %lld to read or write 64-but integers in С++. It is preferred to use the cin, cout streams or the %I64d specificator.
2 1000 1000
2000
1 2
2
大意:寻找最小的n满足 其中ai是事先给定的。
对于所涉及到的所有的因子找出对应的素因子的个数,然后以素因子的个数主遍历,寻找最小值n二分次遍历(“<=”二分),避免超时。
基础很重要!!提交了17次才对T_T
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> using namespace std; typedef long long LL; const int M=1e7+10; int pre[M]; LL cnt[M]; vector<int> pv; void getpre(){ for(int i=2;i<M;i++){ if(!pre[i]){ pre[i]=i; pv.push_back(i); } int len=pv.size(); for(int j=0;j<len&&i*pv[j]<M;j++){ pre[i*pv[j]]=pv[j]; if(i%pv[j]==0) break; } } } LL cal(LL m,int d){ LL ans=0; while(m>=d){ ans=ans+m/d; m=m/d; } return ans; } LL midfind(int d,LL sum){ LL low=1,high=sum,mid,ans=sum; while(low<=high){ mid=(high+low)>>1; if(cal(mid,d)>=cnt[d]){ ans=mid; high=mid-1; } else low=mid+1; } return ans; } int main(){ //freopen("cin.txt","r",stdin); int k,a,Max; getpre(); while(cin>>k){ memset(cnt,0,sizeof(cnt)); Max=0; LL sum=0; for(int i=0;i<k;i++){ scanf("%d",&a); cnt[a]++; sum+=a; Max=max(Max,a); } for(int i=Max-1;i>=2;i--){ cnt[i]+=cnt[i+1]; } for(int i=Max;i>=2;i--){ if(pre[i]!=i){ cnt[pre[i]]+=cnt[i]; cnt[i/pre[i]]+=cnt[i]; } } int len=pv.size(); LL ans=1; for(int i=0;i<len;i++){ ans=max(ans,midfind(pv[i],sum)); } printf("%I64d\n",ans); } return 0; }