用唯一分解定理视角看待模运算
- 问题背景
给定两个数 p 和 q ,若 p % q == 0 ,求 满足条件 ( p%x==0 && x% q !=0 )x的最大值.
- 首先来看一组例子
6 % 4 != 0
6 % 2 == 0
6 分解质因数为: 21 ×3 1
4 分解质因数为: 22
2 分解质因数为: 21
根据 6、4、2 的素因子分解式子的每一项的幂次和模运算结合着看,有没有发现:6%4!=0 的原因是 6 的 21
小于 4 的 2 2 ,而模运算结果为 0 是因为2 的素因子项 21 <= 21
- 得出结论
若两个数 a ,b 进行模运算为 0 ,那么存在 a 的素因子分解式子的每一项 完全包含或者完全被包含 b 的素因子分解式子 (这里的包含指的是 a 的每一个素数项的幂次 大于或等于 b 的每一素数项的幂次)
- 解决问题
由于 p % q == 0 &&p>q,所以 p 的每个素因子项完全包含 q 的每个素因子项,若想找到 一个 满足条件的 x ,可使 x初始值为 p ,然后去让某个素因子项 小于 q 的某个素因子项 ,这样 x %p !=0 ,并且由于 p 的每个素因子项 完全包含 x 的 ,所以 p % x == 0
题目来自 :CodeForces 1445C
撸代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
int main() {
int tt;
scanf("%d",&tt);
while(tt--){
long long p,q;
scanf("%lld%lld",&p,&q);
long long Q=q;
long long ans=0;
for(long long i=2;i*i<=q;i++)//将 q 分解质因子 为 i
if(q%i==0){
while(q%i==0) q/=i;
long long ss=p;
while(ss%Q==0) ss/=i;//若 p%q==0 说明 p 的质因子 i 的幂次大于等于 q 的质因子 i 的幂次
ans=max(ans,ss);
}
if(q>1){
long long ss=p;
while(ss%Q==0) ss/=q;
ans=max(ans,ss);
}
printf("%lld\n",ans);
}
return 0;
}