链接: 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;
}