题目链接
https://codeforces.com/contest/1497/problem/E1
思路
我们都知道,任何一个大于等于2的整数,都能写成若干个质数幂的乘积的形式,如果两个数的乘积是完全平方数,那么这个乘积写成的质数幂的乘积形式后,所有质数的指数一定全部都是偶数,那么我们在预处理的时候可以把每个数的质数幂里面,指数为偶数的部分剔除,例如
12
=
4
∗
3
=
2
2
∗
3
12=4*3=2^2*3
12=4∗3=22∗3,那么只存储存一个3即可。预处理1~1e7所有的数之后,然后对于每个样例都用set或者map存储一下每个数对应的刚刚预处理的值,发现有重复就要新开一组,否则继续存储。关于处理方式采用线性筛的基础上处理。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e7 + 5;
int np[N], p[N], f[N], pn; //f[i]存储去除偶数次方质因数后的数;p[i]存储质数;np[i]标记数组,1是合数
int main(){
f[1] = 1;
for(int i = 2; i < N; i ++){
if(!np[i])
{
f[i] = i;
p[pn ++] = i;
}
for(int j = 0; j < pn; j ++){
int k = i * p[j];
if(k >= N)
break;
np[k] = 1;
if(f[i] % p[j])
f[k] = f[i] * p[j];
else
f[k] = f[i] / p[j];
if(i % p[j] == 0)
break;
}
}
/*for (int i = 0; i < 100;i++)
{
cout << f[i] << ' ';
}
puts("");*/
int T;
cin >> T;
while(T--)
{
int n, k, ans = 1;
cin >> n >> k;
set<int> s;
for(int i = 0, a; i < n; i ++){
cin >> a;
if(s.count(f[a]))
{
ans ++;
s.clear();
}
s.insert(f[a]);
}
cout << ans << "\n";
}
return 0;
}