合适数对
作者:互联网
合适数对
给定一个长度为 $n$ 的正整数数列 $a_{1},a_{2}, \dots ,a_{n}$ 和一个正整数 $k$。
请你判断共有多少个数对 $\left( {l,r} \right)$ 同时满足:
- $1 \leq l < r \leq n$
- 存在一个整数 $x$ 使得 $a_{l} \times a_{r} = x^{k}$ 成立
输入格式
第一行包含两个整数 $n,k$。
第二行包含 $n$ 个正整数 $a_{1},a_{2}, \dots ,a_{n}$。
输出格式
一个整数,表示满足条件的数对的数量。
数据范围
前三个测试点满足 $2 \leq n \leq 10$。
所有测试点满足 $2 \leq n \leq {10}^{5},2 \leq k \leq 100,1 \leq a_{i} \leq {10}^{5}$。
输入样例:
6 3 1 3 9 8 24 1
输出样例:
5
解题思路
这题需要用到算术基本定理。对于一个数$N = P_{1}^{\alpha_{1}} \cdot P_{2}^{\alpha_{2}} \cdot \cdots \cdot P_{n}^{\alpha_{n}}$,如果$N$是$k$次幂的话,那么就有$k \mid \alpha_{i}, \left( {i=1,2,\dots,n} \right)$,否则就至少存在一个$\alpha_{i}$,有$k \nmid \alpha_{i}$。因此这道题目就是要任意找两个数$a_{i}$和$a_{j}$,使他们的乘积$a_{i} \times a_{j}$的所有质因子的次幂都满足$k \mid \alpha_{i}$,问有多少对这种数。
我们枚举$j$,看$j$前面有多少个$a_{i}$使得$a_{i} \times a_{j}$满足条件。先把$a_{j}$进行质因数分解,得到$a_{j} = P_{1}^{\alpha_{1}} \cdot P_{2}^{\alpha_{2}} \cdot \cdots \cdot P_{n}^{\alpha_{n}}$,由于我们只关心质因数的次数是否为$k$的倍数,因此我们只需要关心质因数的次数模$k$后是否等于$0$。对于要找的$a_{i} = P_{1}^{\beta_{1}} \cdot P_{2}^{\beta_{2}} \cdot \cdots \cdot P_{n}^{\beta_{n}}$,应该满足$k \mid \left( \alpha_{i} + \beta_{i} \right)$(这是对应质因子的次数相加,如果具有不同的质因子,那么另一个数对应的次幂应该等于$0$,同样满足)。
由于每一个$a_{i} \leq {10}^{5}$,我们可以估算一下一个数可以最多分解到多少个不同的质因数,有$2 \times 3 \times 5 \times 7 \times 11 \times 13 \times 17 > {10}^{5}$,因此可以发现每个数最多可以分解到$6$个不同的质因子。因此每个数最多只有$6$给质因子的次幂需要补充为$k$的倍数。
对于$a_{j}$,我们找到它分解质因数后所有次幂不是$k$的倍数的质因子,假设为$P_{i}$,假设这些质因子的次幂模$k$后为$r_{i}$,容易发现$1 \leq r_{i} < k$。对于$a_{i}$,其质因数分解后与$a_{j}$相对应的$P_{i}$的次幂模$k$后为$t_{i}$,如果对于所有的$r_{i} + t_{i} = k$都满足,那么这个就是我们要找的$a_{i}$。补充:因为$1 \leq r_{i} < k, 1 \leq t_{i} < k$,$r_{i} + t_{i} < 2 \cdot k$,因此小于$2 \cdot k$且能被$k$整除的数就只有$k$。
我们可以直接用次幂模$k$后不为$0$的质因子的乘积进行哈希,例如上面的$P_{1}^{r_{1}} \cdot P_{2}^{r_{2}} \cdot \cdots \cdot P_{n}^{r_{n}}$,$P_{1}^{t_{1}} \cdot P_{2}^{t_{2}} \cdot \cdots \cdot P_{n}^{t_{n}}$。
AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 typedef long long LL; 6 7 const int N = 1e5 + 10; 8 9 int cnt[N]; 10 11 LL power(int a, int b) { 12 LL ret = 1; 13 while (b--) { 14 ret *= a; 15 if (ret >= N) return 0; // 由于ai都满足<=1e5,因此大于1e5就没有意义了 16 } 17 return ret; 18 } 19 20 int main() { 21 int n, k; 22 scanf("%d %d", &n, &k); 23 24 LL ret = 0; 25 while (n--) { 26 int val; 27 scanf("%d", &val); 28 29 LL p = 1, q = 1; // p表示对aj来说,次幂模k后不为0的质因子的乘积;q表示对于要找的ai,次幂互补的质因子的乘积 30 for (int i = 2; i <= val / i; i++) { // 对aj分解质因数 31 int t = 0; 32 while (val % i == 0) { 33 t = (t + 1) % k; 34 val /= i; 35 } 36 37 if (t) { // 次幂不为0才需要相乘 38 p *= power(i, t); // i^t,累乘的结果必然不超过1e5 39 q *= power(i, k - t); // 相同质因子的次幂要互补,即i^(k-t),累乘的结果可能超过1e5 40 if (q >= N) q = 0; // 超过1e5就没有意义了,赋值为0 41 } 42 } 43 if (val > 1) { 44 p *= val; 45 q *= power(val, k - 1); 46 if (q >= N) q = 0; 47 } 48 49 ret += cnt[q]; 50 cnt[p]++; 51 } 52 53 printf("%lld", ret); 54 55 return 0; 56 }
上面的质因数分解的时间复杂度为$O \left( n \cdot \sqrt[]{n} \right)$。我们还可以用线性筛,因为线性筛可以得到每一个数的最小质因子,因此在分解质质因数时可以用最小质因子来进行分解,每一个数包含的质因子个数大约为$log~n$个,因此这种方法的时间复杂度为$O \left( n \cdot log~n \right)$的。
AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 typedef long long LL; 6 7 const int N = 1e5 + 10; 8 9 int primes[N], cnt, minp[N]; 10 bool vis[N]; 11 int mp[N]; 12 13 void get_prime(int n) { 14 for (int i = 2; i <= n; i++) { 15 if (!vis[i]) { 16 primes[cnt++] = i; 17 minp[i] = i; 18 } 19 for (int j = 0; primes[j] <= n / i; j++) { 20 vis[primes[j] * i] = true; 21 minp[primes[j] * i] = primes[j]; 22 if (i % primes[j] == 0) break; 23 } 24 } 25 } 26 27 LL power(int a, int b) { 28 LL ret = 1; 29 while (b--) { 30 ret *= a; 31 if (ret >= N) return 0; 32 } 33 return ret; 34 } 35 36 int main() { 37 int n, k; 38 scanf("%d %d", &n, &k); 39 40 get_prime(N); 41 42 LL ret = 0; 43 while (n--) { 44 int val; 45 scanf("%d", &val); 46 47 LL p = 1, q = 1; 48 while (val > 1) { 49 int t = minp[val], s = 0; 50 while (val % t == 0) { 51 s = (s + 1) % k; 52 val /= t; 53 } 54 55 p *= power(t, s); 56 if (s) q *= power(t, k - s); 57 if (q >= N) q = 0; 58 } 59 60 ret += mp[q]; 61 mp[p]++; 62 } 63 64 printf("%lld", ret); 65 66 return 0; 67 }
参考资料
AcWing 4319. 合适数对(AcWing杯 - 周赛):https://www.acwing.com/video/3751/
标签:leq,cdot,数对,ret,times,int,合适,alpha 来源: https://www.cnblogs.com/onlyblues/p/16062423.html