山东省第六届ACM程序设计竞赛 Cube Number (唯一分解定理)

Cube Number

  2000 ms         65536 KiB
Submit Status My Status  Origin

Description

In mathematics, a cube number is an integer that is the cube of an integer. In other words, it is the product of some integer with itself twice. For example, 27 is a cube number, since it can be written as 3 * 3 * 3. 

Given an array of distinct integers (a1, a2, ..., an), you need to find the number of pairs (ai, aj) that satisfy (ai * aj) is a cube number.

Input

The first line of the input contains an integer T (1 ≤ T ≤ 20) which means the number of test cases. 

Then T lines follow, each line starts with a number N (1 ≤ N ≤ 100000), then N integers followed (all the integers are between 1 and 1000000).

Output

For each test case, you should output the answer of each case.

Sample

Input

Copy1   
5   
1 2 3 4 9

Output

Copy2

题意:有n个数有多少对数相乘可以变成一个数的三次方。

本身就是一个数3次方的数和 “1”可以分成同一类,用sum0表示,sum0*(sum0-1)就是这些的组合个数。

剩下的数用唯一分解定理分解,分解出来的质因子个数只保留对3取模之后剩下的个数,然后记下剩下来的质数的乘积,然后找出来这个数的另一半有多少个,加上就可以。


比如: 2*2*3*5   记下来 2*2*3*5 和2*3*5    然后2*3*3*5*5 记下来2*3*3*5*5和2*3*5

对2*2*3*5找     (2*3*5)^3 / (2*2*3*5)有多少个就是可以与2*2*3*5组成3次方的个数。

对2*3*3*5*5找   (2*3*5)^3 / (2*3*3*5*5)有多少个就是可以与2*3*3*5*5组成3次方的个数。


注意不要重复计算!!!!


#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
int sum0, vis[1000005], k;
struct Factor{
	ll data, tdata;
}fa[200005];

void decompose(ll x){
	for(ll i = 2; i * i <= x; i++){
		if(x % i == 0){
			ll temp = i, Count = 0;
			while(x % i == 0){
				x /= i;
				Count++;
			}
			if(Count % 3 != 0){
				for(int j = 0; j < Count % 3; j++)
					fa[k].data *= temp;
				fa[k].tdata *= temp;
			}
		}
	}
	
	if(x > 1){
		fa[k].data *= x;
		fa[k].tdata *= x;
	}
	
	if(fa[k].data > 1){	
		vis[fa[k].data]++;
		k++;
	}
	else
		sum0++;
}

int main()
{
	int T, n; 
	scanf("%d", &T);
	while(T--){
		for(int i = 0; i <= 100005; i++)
			fa[i].data = fa[i].tdata = 1;
		int ans = 0;
		sum0 = k = 0;
		memset(vis, 0, sizeof(vis));
		scanf("%d", &n);
		for(int i = 0; i < n; i++){
			ll t;
			scanf("%lld", &t);
			if(t == 1)
				sum0++;
			else
				decompose(t);
		}
		ans += sum0 * (sum0 - 1) / 2;
		
		for(int i = 0; i < k; i++){
			vis[fa[i].data]--;
			ll temp = fa[i].tdata * fa[i].tdata * fa[i].tdata / fa[i].data;
			if(temp < 1000005)
				ans += vis[temp];
		}
		printf("%d\n", ans);
	}
	return 0; 
 }


猜你喜欢

转载自blog.csdn.net/sxh759151483/article/details/80184872