D. Power Products

tech2023-07-23  108

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; }

 

最新回复(0)