【codeforces 1225D】Power Products

題意

計算滿足aiaj=xk,i<ja_{i}*a_{j}=x^k,i<j的對數。

思路

考慮xy=pkx*y=p^k,將xxyy進行質因子分解可得:
x=p1m1p2m2p3m3...pnmn x=p_1^{m_1}p_2^{m_2}p_3^{m_3}...p_n^{m_n}
y=q1t1q2t2q3t3...qntn y=q_1^{t_1}q_2^{t_2}q_3^{t_3}...q_n^{t_n}

如果對於xxyy有着不同的質因子,那麼該質因子的次數一定是kk的倍數,如果有着相同的質因子,那麼ti+mit_i+m_i也一定是kk的倍數,因此,可以考慮把aia_i進行質因子分解,將冪次模kk後構造成新的數字即可把每個數字壓縮,這樣只需要考慮ti+mi=kt_i+m_i=k的情況,利用map存一下然後O(n)O(n)的掃一遍即可。

代碼

#include<bits/stdc++.h>

using namespace std;
const int N = 1e6+100;
long long a[N],b[N];
typedef long long ll;
map<ll,ll> nums;
ll qp(ll a,ll b){
	ll ans=1;
	while(b){
		if(b&1) ans=ans*a;
		a=a*a;
		b>>=1;
	}
	return ans;
}
int main(){
	long long n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=n;i++){
		ll now=1;
		ll need=1;
		for(ll j=2;j*j<=a[i];j++){
			if(a[i]%j==0){
				int cnt=0;
				while(a[i]%j==0){
					++cnt;
					a[i]/=j;
				}
				cnt%=k;
				now*=qp(j,cnt);
			}
		}
		if(a[i]!=1){
			 now*=a[i];
		}
		a[i]=now;
		nums[a[i]]++;
		for(ll j=2;j*j<=now;j++){
			if(now%j==0){
				int cnt=0;
				while(now%j==0){
					++cnt;
					now/=j;
				}
				need*=qp(j,k-cnt);
			}
		}
		if(now!=1){
			 need*=qp(now,k-1);
		}
		b[i]=need;
	}
	ll ans=0;
	for(int i=1;i<=n;i++){
		if(b[i]==a[i]){
			ans+=nums[b[i]]-1;
		}else{
			ans+=nums[b[i]];
		}
	}
	cout<<ans/2<<endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章