合适数对(算术基本定理)
题意
给定一个长度为 的正整数数列 和一个正整数 。
请你判断共有多少个数对 同时满足:
- 存在一个整数 使得 成立
数据范围
思路
数对个数问题,常规套路就是枚举一端,另一端可以通过前面处理的信息直接算出。在这里,我们枚举,那么如何求呢?
考虑算术基本定理。我们将分解质因数,每个质因子的次数必然是的倍数。
因此,我们对分解质因数,将所有质因数的次数对取模。对于每一个次数为的质因数,在中,的次数必须为。
那么统计的个数呢?可以考虑哈希。在这里,哈希方式就是剔除所有次数为的质因子,将其他各项相乘。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 100010;
int n;
ll k;
ll cnt[N];
ll qmi(ll a, ll b)
{
ll res = 1;
while(b --) {
res *= a;
if(res >= N) {
res = 0;
break;
}
}
return res;
}
int main()
{
scanf("%d%lld", &n, &k);
ll ans = 0;
for(int i = 1; i <= n; i ++) {
ll x;
scanf("%lld", &x);
ll p = 1, con_p = 1;
for(int j = 2; j <= x / j; j ++) {
if(x % j == 0) {
ll s = 0;
while(x % j == 0) {
s ++;
x /= j;
}
s %= k;
if(s) {
p *= qmi(j, s);
con_p *= qmi(j, k - s);
}
}
}
if(x > 1) {
p *= qmi(x, 1);
con_p *= qmi(x, k - 1);
}
if(con_p >= N) con_p = 0;
ans += cnt[con_p];
cnt[p] ++;
}
printf("%lld\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】