Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2)D - Power Products

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_42671946/article/details/102764469

D. Power Products

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

You are given nn positive integers a1,…,ana1,…,an, and an integer k≥2k≥2. Count the number of pairs i,ji,j such that 1≤i<j≤n1≤i<j≤n, and there exists an integer xx such that ai⋅aj=xkai⋅aj=xk.

Input

The first line contains two integers nn and kk (2≤n≤1052≤n≤105, 2≤k≤1002≤k≤100).

The second line contains nn integers a1,…,ana1,…,an (1≤ai≤1051≤ai≤105).

Output

Print a single integer — the number of suitable pairs.

Example

input

Copy

6 3
1 3 9 8 24 1

output

Copy

5

Note

In the sample case, the suitable pairs are:

  • a1⋅a4=8=23a1⋅a4=8=23;
  • a1⋅a6=1=13a1⋅a6=1=13;
  • a2⋅a3=27=33a2⋅a3=27=33;
  • a3⋅a5=216=63a3⋅a5=216=63;
  • a4⋅a6=8=23a4⋅a6=8=23.

分析:首先我们对于每个数进行一个预处理,质因子分解后将其幂模上k,然后计数的时候只需要计算与其互补的值就可以了。简单的用map维护记录一下就可以了。

#include <bits/stdc++.h>
using namespace std;
long long a[100004];
bool vis[100004];
long long prim[100004];
long long p[100004];
long long cnt;
int main(){
    long long n,k;
    cin>>n>>k;
    for (int i = 1; i <= n; ++i) {
        scanf("%lld",&a[i]);
    }
    cnt = 0;
    for (int i = 2; i < 100004; ++i) {
        if(!vis[i])prim[cnt++]=i;
        for (int j = 0; j < cnt && i*prim[j] < 100004; ++j) {
            vis[i*prim[j]]=1;
            if(i%prim[j]==0)break;
        }
    }
    bool ok = 0;
    for (int i = 0; i < cnt; ++i) {
        p[i]=prim[i];
        if(ok)continue;
        prim[i]=1;
        for (int j = 0; j < k && !ok; ++j) {
            prim[i]*=p[i];
            if(prim[i] > 1000000000000LL)ok=1;
        }
    }
    unordered_map<long long,int>mp;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < cnt && prim[j] <= a[i]; ++j) {
            while(a[i]%prim[j] == 0)a[i]/=prim[j];
        }
        mp[a[i]]++;
    }
    long long ans = 0;
    for (int i = 1; i <= n; ++i) {
        mp[a[i]]--;
        long long temp = 1;
        long long now = a[i];
        for (int j = 0; j < cnt; ++j) {
            if(p[j]>now)break;
            if(p[j]==prim[j])break;
            if(now%p[j]==0){
                temp*=prim[j];
            }
            while(now%p[j]==0){
                now/=p[j];
                temp/=p[j];
            }
            if(temp > 100000)break;
        }
        if(temp<=100000){
            if(temp == 1 && a[i]==1){
                ans += mp[temp];
            }
            else if(temp != 1)ans += mp[temp];
        }
        mp[a[i]]++;
    }
    cout<<ans/2<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42671946/article/details/102764469