题目链接:SDUT3258
题目大意:
一个整数,可以被表示为另一个整数的平方,这个整数称为平方数。
给你一个序列ai ~aj,规模为1e5,让你找出有多少对(ai,aj),使得ai×aj为平方数。
思路
唯一分解定理:任何一个大于1的数,都可以拆分成若干素数的乘积。
有了这个定理再看题目要求可知,平方数就一定能表示为若干素数的偶次幂的乘积。
所以枚举所有的素因子,如果出现偶次幂,忽略,如果是奇次幂就记录在对于的位置factor[ n ]++。
最后统计有多少个可以配对的因数就行了。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn = 1000000 + 10;
bool isprime[maxn];
int prime[maxn];
int num[maxn/10];
int factor[maxn];
int k = 0 ;
void init(){
isprime[0]=1, isprime[1] =1;
for(int i=2;i<=sqrt((double)maxn);i++){
if(!isprime[i]){
prime[k++] = i;
for(int j = i*2;j<=maxn;j+=i)
isprime[j] = 1;
}
}
}
int main(){
int t;
init();
scanf("%d",&t);
while(t--){
long long ans = 0;
int n;
memset(factor,0,sizeof(factor));
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
for(int i=0;i<n;i++){
int t = num[i];
int remain = 1;
for(int j = 0;j<k;j++){
int times = 0;
while(t % prime[j] == 0){
t/=prime[j];
times ++;
}
if(times & 1){ //如果是奇数个素因子
remain*=prime[j];
}
if( !isprime[t] || t == 1){ //如果
remain*=t;
break;
}
}
ans += factor[remain];
factor[remain]++;
}
printf("%lld\n",ans);
}
return 0;
}
题目链接:SDTU3257
和上一个题一样,不过这题求得是立方数。
一样的思路,如果素因子出现的次数是3的倍数,忽略, 如果mod3 == 1,那么就去找mod3 == 2的配对, 如果 mod3 == 2,就去找mod3 == 1的配对。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn = 1000000 + 10;
bool isprime[maxn];
int prime[maxn];
int num[maxn/10];
int factor[maxn];
int k = 0 ;
void init(){
isprime[0]=1, isprime[1] =1;
for(int i=2;i<=1000;i++){ //只需要找1000下的素数即可
if(!isprime[i]){
prime[k++] = i;
for(int j = i*2;j<=1000;j+=i)
isprime[j] = 1;
}
}
}
int main(){
int t;
init();
scanf("%d",&t);
while(t--){
long long ans = 0;
int n;
memset(factor,0,sizeof(factor));
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
for(int i=0;i<n;i++){
int t = num[i];
long long self = 1; //代表自己多余的因数
long long partner = 1; //代表需要配对的因数
int isadd = 0;
for(int j = 0;j<k;j++){
int times = 0;
while(t % prime[j] == 0){
t/=prime[j];
times ++;
}
if(times % 3 == 1){
self*=prime[j];
partner = partner*prime[j]*prime[j];
}
else if(times % 3 == 2){
self = self*prime[j]*prime[j];
partner*=prime[j];
}
if(partner >1000000 ||self >1000000 ){ //如果超1000000则不可能有配对
isadd = 0;break;
}
if(t == 1){
isadd = 1;break;
}
}
if(isadd && t == 1){
ans += factor[partner];
factor[self]++;
}
}
printf("%lld\n",ans);
}
return 0;
}