2505T2
吐槽:\(O(tn\pi(\sqrt a_i))\) 能过也是刷新我对评测机的认识了,强烈建议加强数据。
本题给了你 \(n\) 个数,\(a_1,a_2,\dots,a_n\),要你求最多保留几个数,使得剩下的数两两的乘积不为平方数。
好可以,首先我们知道两个数乘积是完全平方数当且仅当它们乘起来后质因数分解每个质数的次数都是偶数,根据奇偶数加法的性质,可以看出这两个数质因数分解后的每一项的次数的奇偶性都相同。既然奇偶性相同,那么次数的多少就没必要考虑了,所以可以把每个数的平方因子都去掉。
那么答案就是每个数去掉平方因子后不同的数的个数。
好。现在我们考虑怎么去掉每个数的平方因子,和质因数分解类似,先处理出 \(1~\sqrt a_i\) 内每个质数和它的平方。接着,枚举质数的平方,使得 \(p^2 \leq \sqrt a_i\),并将 \(a_i\) 除以能整除 \(a_i\) 的 \(p^2\)。
这一部分的时间复杂度是 \(O(\pi(a_i^{\frac{1}{4}}))\)。
和质因数分解的分析类似,此时 \(a_i\) 中最多剩下一个平方因子。考虑去掉它。
先特判一下 \(a_i\) 是完全平方数的情况。
接着枚举质数 \(p\),使得 \(p^3\leq a_i\)。
为什么呢?因为现在剩下了一个质因子,且它要大于 \(a_i^{\frac{1}{4}}\),那么如果它小于等于 \(a_i^{\frac{1}{3}}\),那么我们肯定能枚举到,否则如果它大于 \(a_i^{\frac{1}{3}}\) 那么它的平方就大于 \(a_i^{\frac{2}{3}}\),a_i 除以它的平方就小于 \(a_i^{\frac{1}{3}}\),而这个数也可以被枚举到。
那么我在枚举 \(p\) 的时候,就可以判断它是否是 \(a_i\) 的平方因子,如果它是,\(a_i\) 就除以 \(p^2\)。否则如果它是 \(a_i\) 的因子,给一个累乘器 \(t\) 乘上 \(p\)。然后判断 \(\frac{a_i}{t}\) 是不是平方数。
总复杂度 \(O(tn\pi({a_i^{\frac{1}{3}}}))\)。好球!
for(int i=1;i<=n;i++){
//pr 是质数的平方,pp 是质数
for(int j=1;pr[j]*pr[j]<=a[i];j++){
while(a[i]%pr[j]==0){
a[i]/=pr[j];
}
}
//除去小于 a_i^1/4 的平方因子
int tmp=1;
for(int j=1;pp[j]*pp[j]*pp[j]<=a[i];j++){
if(a[i]%(pr[j])==0){//按上面的两种情况分类
// 大于 a_i^1/4 小于 a_i^1/3
a[i]/=pr[j];
break;
}
else{
if(a[i]%pp[j]==0){
//大于 a_i^1/3
tmp*=pp[j];
int tp=a[i]/tmp,sq=sqrt(tp);
if(sq*sq==tp){
a[i]=tmp;
break;
}
}
}
}
int sq=sqrt(a[i]);
if(sq*sq==a[i]){//特判a_i是平方数
a[i]=1;
}
}

浙公网安备 33010602011771号