题意:
给你m1,m2,现在有 M = m 1 m 2 M = m1^{m2} M=m1m2个试管,n种细胞,每种细胞经过1s可以分裂成 a i a^i ai个细胞,问你可以将细胞平均分配到M个试管的最短时间。
思路:
先得出m1的质因数集合s1以及这些m1中这些质因数的个数,可以想到:如果i细胞可以在有限的时间内得到合适的数量使其可以分配到M个试管中去,那么i细胞每次分裂的个数ai,它的质因数集合设为s2,则s1一定包含于s2。
于是,s2集合里的质因数每秒加1,而s1里的每种质因数的个数应该还需要乘上m2,最后我们只需要计算出s2里的和s1同种的质因数数量超过s1最多需要多少秒,最后比较所有符合条件的ai即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll prims[100000];
ll vis[1000010];
ll cnt = 0;
void prim()
{
for(ll i=2;i<=10000;i++)
{
if(!vis[i])
{
prims[++cnt]=i;
}
for(ll j=1;j<=cnt;j++)
{
if(prims[j]*i<=10000)
vis[prims[j]*i]=1;
else
break;
if(i%prims[j]==0)
break;
}
}
}
ll same[10000];
ll m_prim[10000];
ll ans[100000];
ll m_sum[10000];
ll a[10010];
ll now_prim[10000];
ll num_prim[10000];
ll sum_prim[10000];
int main()
{
ll n;
cin>>n;
ll m1,m2;
cin>>m1>>m2;
prim();
for(ll i = 1; i <= n; i++) cin>>a[i];
ll num = 0;
for(ll i = 1; i <= cnt; i++)
{
if(m1%prims[i] == 0)m_prim[++num] = prims[i];
while(m1%prims[i] == 0)same[prims[i]]++,m1 /= prims[i];
if(prims[i] > m1)break;
}
ll ans_num = 0;
for(ll i = 1; i <= n; i++)
{
ll flag = 0;
for(ll j = 1; j <= cnt; j++)
{
if(flag == num)break;
if(a[i]%prims[j] == 0)
{
if(m_prim[++flag] < prims[j])
{
flag = -1;
break;
}
else if(m_prim[flag] > prims[j])flag--;
}
}
if(flag == num)ans[++ans_num] = a[i];
}
if(ans_num == 0)
{
cout<<-1<<endl;
return 0;
}
for(ll i = 1; i <= num; i++)
{
sum_prim[i] = same[m_prim[i]]*m2;
}
ll res = 0x7f7f7f7f;
for(ll i = 1; i <= ans_num; i++)
{
ll now = ans[i];
ll flag = 0;
for(ll j = 1; j <= num; j++)
{
if(now%m_prim[j] == 0)
{
now_prim[++flag] = m_prim[j];
while(now%m_prim[j] == 0)
{
now /= m_prim[j];
num_prim[m_prim[j]]++;
}
if(m_prim[j] > now || flag == num)break;
}
}
ll c = 0;
for(ll j = 1; j <= num; j++)
c = max(c, (ll)ceil(sum_prim[j]*1.0/num_prim[now_prim[j]]));
res = min(c, res);
memset(num_prim,0,sizeof(num_prim));
}
cout<<res<<endl;
}