开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情
【Codeforces】Educational Codeforces Round 139 (Div. 2) D. Lucky Chains | 质因数分解
题目链接
题目
题目大意
给定 和 ,求最小的非负整数 使得
如果 不存在,输出 -1
。
思路
假设
即 是 的因数,也是 的因数。那么一定有
即 。
所以当且仅当 时,未知数为 的方程 有非负整数解,最小的非负整数解为 。
对于任三个正整数 ,显然有
所以我们只需要对 所有的质因数分别求出对应的 ,取最小值即可。质因数分解时,可以先把 范围内的质数先筛出来加快求解。(也可以使用线性筛记录每个合数的最小质因数,直接 进行质因数分解)。
最终解题流程为:
- 当 时,我们直接输出
0
。 - 当 时,我们直接输出
-1
。 - 其他情况我们枚举 的质因数,求解最小的 即可。
代码
#include <stdio.h>
#include <algorithm>
using namespace std;
using LL=long long;
const int N=1e6+5,M=3201;
const LL mod=1e9+7;
int n,m,k;
int v[M],p[M],tot;
int gcd(int a,int b)
{
if (b==0) return a;
return gcd(b,a%b);
}
LL solve()
{
scanf("%d%d",&n,&m);
if (gcd(n,m)!=1) return 0;
k=m-n;
if (k==1) return -1;
int ans=k-n%k;
for (int i=1;i<=tot&&p[i]*p[i]<=k;++i)
{
if (k%p[i]!=0) continue;
while (k%p[i]==0) k/=p[i];
ans=min(ans,p[i]-n%p[i]);
}
if (k!=1) ans=min(ans,k-n%k);
return ans;
}
int main()
{
int T=1;
n=M-1;
for (int i=2;i<=n;++i)
{
if (!v[i]) p[++tot]=i;
for (int j=1;j<=tot&&i*p[j]<=n;++j)
{
v[i*p[j]]=1;
if (i%p[j]==0) break;
}
}
scanf("%d",&T);
while (T--) printf("%lld\n",solve());
return 0;
}