题意
构造b数组,元素乘积等于a数组元素乘积,且所有元素都要是“强合数”,求b数组长度k的最大值。
分析
看看样例,想一个数怎样才能成为强合数。
发现三个不同质数的乘积或者一个质数的平方一定是一个强合数。为了让数组更长,优先选择质数的平方。
于是就可以把a数组的乘积进行质因数分解,然后去除每个质数的平方,最后三个三个组合就行。
但是,直接乘起来会爆掉,所以碰到一个 a i a_i ai 就分解。
但是我还是没过。。。超时了。。
有一个重要处理:在线性筛的时候记录每个数的最小质因子,分解质因数的时候就从最小质因子开始,直接可以跳到每个数的质因子,不用一个个枚举。
上代码
![#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
int t,n;
int p[1000100],tot,kk[1000100],f[10001000];
bool v[10000010];
ll cnt,ans;
void pre()
{
for(int i=2;i<=10000000;i++)
{
if(!v[i]) p[++tot]=i,f[i]=tot;
for(int j=1;j<=tot&&i*p[j]<=10000000;j++)
{
v[i*p[j]]=1;
f[i*p[j]]=j;//记录
if(i%p[j]==0) break;
}
}
}
int main()
{
pre();
cin>>t;
while(t--)
{
scanf("%d",&n);
for(register int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
int j=f[x];
while(x>1)
{
j=f[x];
while(x%p[j]==0)
{
x/=p[j];
kk[j]++;
cnt++;
}
}
}
for(register int i=1;i<=tot;i++)
{
ans+=(kk[i]/2);
cnt-=2*(kk[i]/2);
}
ans+=cnt/3;
printf("%lld\n",ans);
ans=0;
cnt=0;
memset(kk,0,sizeof(kk));
}
return 0;
}