题目
题解思路
由算术基本定理,可以将每个ai拆分成若干个质数的幂次的乘积。
如果想构成x的k次方,两个数拆分的每个质数的幂次也必须满足相加余k为0。
所以,问题变成了,对这个数我们去找之前可以和他的每个质数的幂次相加余k为0的数的数量。
这好像是个求有几个相同的多元组问题,但是,又有算术基本定理逆向,这样我们可以直接确定我们找的这个多元组对于的数是多少,直接开个map映射即可。(这一步,没想出来)
对每个幂次,我们只关心模k的余数。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<long long ,long long >
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 200100;
long long a[N] ;
void solve()
{
long long n , k ;
cin >> n >> k ;
for (int i = 1 ; i <= n ; i++ )
cin >> a[i] ;
map <long long ,long long > mp ;
long long ans = 0 ;
for (int i = 1 ; i <= n ; i++ )
{
long long sp = a[i] ;
long long lj = 1 ;
long long qy = 1 ;
vector <PII> sk ;
for (long long j = 2 ; j*j <= a[i] ; j++ )
{
if ( sp % j == 0 )
{
int cnt = 0 ;
long long tp = 1 ;
while ( sp % j == 0 )
{
sp/=j;
tp*=j ;
cnt++;
}
if (cnt%k)
{
sk.push_back({j,cnt}) ;
}
}
}
for ( auto j : sk )
{
for (int u = 1 ; u <= j.second ; u++ )
lj*=j.first ;
for (int u = 1 ; u <= k - j.second ; u++ )
qy*=j.first ;
}
ans += mp[qy] ;
mp[lj]++;
}
cout << ans << "\n" ;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
solve() ;
return 0 ;
}