首先显然每个质数是独立的,对于
m
个 都算一次n的下界,最后取
对于一个质数,算满足它至少出现
e
次的最小值,可以很暴力的二分,这样要两个
考虑把
n
转成
然后就贪心的从高位到低位填即可,每次填保证之后合法的最小值。
这样就是
O(T∗m∗logV)
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=555;
int N=550,n,m,b[maxn],p[maxn];
LL ans,a[maxn];
bool vis[maxn];
void Pre(){
for(int i=2;i<=N;i++){
if(!vis[i]) p[++p[0]]=i;
for(int j=1;j<=p[0]&&(LL)i*p[j]<=N;j++){
vis[i*p[j]]=true;
if(i%p[j]==0) break;
}
}
}
LL pw[maxn],w[maxn],sum_w[maxn];
LL Solve(int prm,LL m){
LL res=0; int _max;
w[1]=sum_w[1]=_max=1; pw[0]=1; pw[1]=prm;
for(int i=2;i<=70;i++){
pw[i]=pw[i-1]*prm;
w[i]=w[i-1]+pw[i-1], sum_w[i]=sum_w[i-1]+w[i], _max=i;
if(sum_w[i]*(prm-1)>m) break;
}
for(int i=_max;i>=1;i--){
if(sum_w[i-1]*(prm-1)>=m) continue;
int now=(m-sum_w[i-1]*(prm-1)+w[i]-1)/w[i];
res+=pw[i]*now; m-=now*w[i];
}
return res;
}
int _test;
int main(){
freopen("loj530.in","r",stdin);
freopen("loj530.out","w",stdout);
Pre();
scanf("%d",&_test);
while(_test--){
scanf("%d",&m);
for(int i=1;i<=m;i++) scanf("%lld",&a[i]);
ans=1;
for(int i=1;i<=m;i++) ans=max(ans,Solve(p[i],a[i]));
printf("%lld\n",ans);
}
return 0;
}