Codeforces 1247D. Power Products

传送门

要满足存在 $x$ ,使得 $a_i cdot a_j = x^k$

那么充分必要条件就是 $a_i cdot a_j$ 质因数分解后每个质因数的次幂都要为 $k$ 的倍数

证明显然

设 $a_i=sum_{j=1}^{x}p_j^{t_j}$ ,那么不妨变成 $sum_{j=1}^{x}p_j^{t_j mod k}$

然后考虑固定 $j$,设 $a_j=sum_{k=1}^{x}p_k^{t_k}$ ,只要求有多少 $a_i$ 的值为 $sum_{k=1}^{x}p_k^{k-t_k}$ 即可

用 $map$ 维护一下就行了,具体看代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=2e5+7;
int n,K;
int pri[N],fir[N],tot;
bool not_pri[N];
void pre()
{
    not_pri[1]=1; fir[1]=1;
    for(int i=2;i<N;i++)
    {
        if(!not_pri[i]) pri[++tot]=i,fir[i]=i;
        for(int j=1;j<=tot;j++)
        {
            ll g=1ll*i*pri[j]; if(g>=N) break;
            not_pri[g]=1; fir[g]=pri[j];
            if(i%pri[j]==0) break;
        }
    }
}
map <ll,int> cnt;
int main()
{
    pre();
    n=read(),K=read(); ll ans=0;
    for(int i=1;i<=n;i++)
    {
        int t=read(); vector < pair<int,int> > P;
        while(t!=1)
        {
            int &p=fir[t];
            if((!P.size())||p!=P.back().first)
                P.push_back(make_pair(p,1));
            else P.back().second++;
            t/=p;
        }
        ll x=1,y=1; bool GG=0;
        for(auto d: P)
        {
            for(int j=1;j<=d.second%K;j++)
                x*=d.first;
            for(int j=1;j<=(K-(d.second%K))%K;j++)
            {
                if(y>=N) { GG=1; break; }
                y*=d.first;
            }
        }
        if(!GG) ans+=cnt[y]; cnt[x]++;
    }
    printf("%lld
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/LLTYYC/p/11748422.html