[Acwing4319] 合适数对
[Acwing4319] 合适数对
- 数论算法 同余
给定一个长度为 的正整数数列 和一个正整数 。
请你判断共有多少个数对 同时满足:
- 存在一个整数 使得 成立
输入格式
第一行包含两个整数 。
第二行包含 个正整数 。
输出格式
一个整数,表示满足条件的数对的数量。
数据范围
前三个测试点满足 。
所有测试点满足 。
Acwing
上的一道Hard
难度的周赛题。
首先我们考察这个条件:存在一个整数 使得 成立。注意到 ,因此不妨认为 是正整数。
由算术基本定理,任意一个正整数都能唯一地分解为全体质数的幂积:
于是,我们可以根据上式将任意一个正整数表示为一个无限维行向量:
例如,,那么,。特别地
那么,任意两个正整数的乘法运算就可以转换为向量加法运算:
于是我们知道 ,向量 的每一个元素都能被 整除
那么,我们需要找出的满足 的正整数 满足性质 :
注意到我们并不关心的每个元素的具体值,只关心它们是否都能被 整除。那么,接下来就应该考虑什么情况下两数之和能被 整除。
由同余代数的知识可以知道: 的任意整数倍模 都是 ,如果 ,,那么 ,那么,如果要有 能被 整除,一定有
设 ,那么 ,即
于是,如果我们知道一个数 ,那么所有与 加起来能被 整除的数都与 同余
于是乎,所有与 加起来后每一个元素能被 整除的向量 ,一定满足:
于是,我们就有了解题思路:
-
从前往后枚举每一个元素 ,利用分解质因数算法计算 的向量,求出该向量每个元素模 后的向量 和每个元素取负后再模 的向量
-
在一个记录向量出现次数的数据结构中寻找向量 的出现次数,将它累加到答案
-
将 记录到数据结构,即其出现次数加1
注意到计算向量会有些复杂,因为我们需要知道每个质数在向量中的位置,由于一个正整数和它的向量是唯一对应的,于是在分解质因数时,我们只计算向量 与 对应的正整数值 和 即可。
由于每个质数因子的指数取模后一定不会变大,一定有 。而取负后再取模就很可能变得更大,比如 ,因此 有可能大于 ,这种情况下一定没有 ,要注意判断。
分解质因数的时间复杂度为 ~ ,总时间复杂度为 ~
#include<iostream>
#include<unordered_map>
#include<string>
#include<vector>
#include<cmath>
using namespace std;
typedef unsigned long long ULL;
typedef pair<ULL,ULL> PUU;
const int N = 100010;
PUU K_num_anti(int x, int k){
PUU ans={1,1};
for(int i = 2;i<=x/i;i++){
if(x%i == 0){
int t = 0;
while(x%i == 0){
t++;
x/=i;
}
//求幂
for(int j = 1;j<= (t%k);j++){
ans.first *= i;
}
for(int j = 1;j<=((-t)%k+k)%k;j++){
if(ans.second>N){ans.second = N;break;}
ans.second*= i;
}
}
}
if(x>1){
ans.first *= x;
for(int i = 1;i<=((-1)%k+k)%k;i++){
if(ans.second>N){ans.second = N;break;}
ans.second*= x;
}
}
return ans;
}
unordered_map<ULL,int> fd;
int p[N];
int main(){
int n,k;
scanf("%d%d", &n,&k);
for(int i = 1;i<=n;i++)scanf("%d", p+i);
ULL ans = 0;
for(int i = 1;i<=n;i++){
int num = p[i];
// res 第一个存[ai]k,第二个存 [-ai]k,如果它是大于N的,存N
auto res = K_num_anti(num,k);
if(res.second!=N && fd.find(res.second)!=fd.end())ans += fd[res.second];
if(fd.find(res.first) != fd.end()) fd[res.first]++;
else fd.emplace(res.first,1);
}
printf("%lld\n",ans);
return 0;
}
本文来自博客园,作者:Sarfish,转载请注明原文链接:https://www.cnblogs.com/sarfish/p/16063718.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】