要满足存在 $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\n",ans); return 0; }
原文地址:https://www.cnblogs.com/LLTYYC/p/11748422.html
时间: 2024-11-08 09:57:41