D. Power Products

https://codeforces.com/problemset/problem/1225/D

题目描述

You are given nn positive integers a_1, \ldots, a_na1​,…,an​ , and an integer k \geq 2k≥2 . Count the number of pairs i, ji,j such that 1 \leq i < j \leq n1≤i<j≤n , and there exists an integer xx such that a_i \cdot a_j = x^kai​⋅aj​=xk .

输入格式

The first line contains two integers nn and kk ( 2 \leq n \leq 10^52≤n≤105 , 2 \leq k \leq 1002≤k≤100 ).

The second line contains nn integers a_1, \ldots, a_na1​,…,an​ ( 1 \leq a_i \leq 10^51≤ai​≤105 ).

输出格式

Print a single integer — the number of suitable pairs.

题意翻译

现在给你nn个正整数 [a_1,a_2,...,a_n][a1​,a2​,...,an​] 和一个的正整数k\geq2k≥2,现在请你求出有多少组 (i,j)(i,j) ,满足 (1≤i<j≤n)(1≤i<j≤n)且存在一个整数 xx 满足 a_i\times a_j=x^kai​×aj​=xk

输入格式

输入第一行是两个正整数nn和kk(2≤n≤10^5,2≤k≤100)(2≤n≤105,2≤k≤100)

第二行为nn个正整数[a_1,a_2,...,a^n](1≤a_i≤10^5)[a1​,a2​,...,an](1≤ai​≤105)

输出格式

输出一个整数,表示有多少满足条件的组合

样例说明

样例中有以下几组满足条件的组合

a_1*a_4=8=2^3a1​∗a4​=8=23

a_1*a_6=1=1^3a1​∗a6​=1=13

a_2*a_3=27=3^3a2​∗a3​=27=33

a_3*a_5=216=6^3a3​∗a5​=216=63

a_4*a_6=8=2^3a4​∗a6​=8=23

一共五组,所以输出为55

输入输出样例

输入 #1复制

6 3
1 3 9 8 24 1

输出 #1复制

5

说明/提示

In the sample case, the suitable pairs are:

  • a_1 \cdot a_4 = 8 = 2^3a1​⋅a4​=8=23 ;
  • a_1 \cdot a_6 = 1 = 1^3a1​⋅a6​=1=13 ;
  • a_2 \cdot a_3 = 27 = 3^3a2​⋅a3​=27=33 ;
  • a_3 \cdot a_5 = 216 = 6^3a3​⋅a5​=216=63 ;

暴力的思路沿呈https://blog.csdn.net/zstuyyyyccccbbbb/article/details/108357803

式子转化一下可以得到

但是k==2的时候,预处理的数字个数有1e5个,然后去处理就超时了。(TLE6)

这题有一个结论:两个数的积为 k 次方数,当且仅当每一质因子的次数和都是 k 的倍数。

证明:把两个数分别个分解质因数了。

A=p1^k1*p2^k2*p3^k3....pn^kn;

B=p1^c1*p2^c2*p3^c3.....pn^cn;

对于每个质因数pi,ki+ci为k的整数倍的时候,i与j成功配对

因为i*j=p1^(k1+c1)*p2^(k2+c2)*.....pt^(kt+ct)

此时i*j必为X^k.

那么只有k==2TLE,我们特判k==2的时候。k==2的时候,也就是i*j的每个质因数pi的次数(ki+ci)为2的整数倍。也就是只有在ki和ci同时为奇数或者偶数的时候才成立。

那先预处理1e5以内的质因子,然后对每个a[i]质因数分解,用bitset维护每个a[i]每个质因数出现的次数。然后把bitset存到unordered_map里,查询的时候查里面同奇偶的map[bitset]

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<unordered_map>
#include<cmath>
#include<map>
#include<bitset>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
const int cntp=1e4;//质数个数 
LL n,k1,a[maxn];
LL v[maxn],primes[maxn];//v[i]存的是i的最小质因子,primes[m]里面存筛出来的质数
map<LL,LL>map1;
unordered_map<bitset<cntp>,LL>mp;
LL x[maxn];
LL m=0;//质数个数 
inline LL ksm(LL x,LL a){
	LL ret=1,k=x;
	for (;a;a>>=1,k=k*k)
		if (a&1) ret=ret*k;
	return ret;
} 
void getprimes(int n)
{
	//memset(v,0,sizeof(v));//最小质因子 		
	for(LL i=2;i<=n;i++)
	{
		if(v[i]==0) {v[i]=i;primes[++m]=i;}//i是质数 
		//给当前的数i乘上一个质因子
		for(LL j=1;j<=m;j++)
		{
			//i有比primes[j]更小的质因子,或者超出n的范围,停止循环 
			if(primes[j]>v[i]||primes[j]>n/i)	break;
			//primes[j]是合数i*primes[j]的最小质因子 
			v[i*primes[j]]=primes[j];
		} 
	}
	//for(LL i=1;i<=m;i++) cout<<primes[i]<<endl; 
} 
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  cin>>n>>k1;
  for(LL i=1;i<=n;i++) cin>>a[i];
  sort(a+1,a+1+n);
  if(k1==2)
  {
  	LL ans=0;
	getprimes(100000);
	bitset<cntp>b;
	for(LL i=1;i<=n;i++){
		b.reset();//全置0
		b.set(0);//第0位置赋1
		LL tmp=a[i];
		LL cnt=0;
		for(LL j=1;j<=m;j++)
		{
			while(tmp%primes[j]==0){
				++cnt;tmp/=primes[j];
			}
			if(cnt&1) b.set(j);
			cnt=0;
			if(tmp==1) break;
		} 
		ans+=mp[b];
		mp[b]++;
	}
	cout<<ans<<endl;
  }
  else
  {
  	LL pos=1;//用set TLE11 
  	for(LL i=1; ;i++)
  	{
  	 	x[i]=ksm(i,k1);
  	 	if(x[i]>=1e10) {
  	 		pos=i;break;	
		}
  	}
  	LL ans=0;
  	//枚举右端 
  	for(LL i=1;i<=n;i++)
  	{
  		ans+=map1[a[i]];
  		for(LL j=1;j<=pos;j++)
  		{
  			if((x[j])%a[i]==0)
  			{
  				map1[x[j]/a[i]]++;		
			}
		}
  	}
  	cout<<ans<<endl;
  }
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108384698