Description
求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解。
输入只有一行,包含两个正整数 a, b,用一个空格隔开。
输出只有一行,包含一个正整数 x ,即最小正整数解。输入数据保证一定有解。
Sample Input
3 10
Sample Output
7
对于40%的数据,2 ≤b≤ 1,000;
对于60%的数据,2 ≤b≤ 50,000,000;
对于100%的数据,2 ≤a, b≤ 2,000,000,000。
解法(暴力简介
看到这有层次感的数据分割,很明显,我们可以暴力。
而且,这道题有暴力初阶,暴力中阶,暴力进阶。
所以这些并不是我们今天的主角,所以,我先丢到最后面,想看看的同学往下看……
不想的,可以看到目录上的正解。
初阶(40分)
#include<iostream>
#include<cstdio>
using namespace std;
int
n,m,k=1,ans;
void f(int x,int y)
{
ans=1;
k=x%m;
while(y)
{
if(y%2==1) ans=ans*(k%m)%m;
k=(k*k)%m;
y/=2;
}
}
int main()
{
scanf("%d%d",&n,&m);
f(n,m-3);
while((k%m)*(n%m)%m!=1)
k=(k%m)*(n%m);
printf("%d",k%m);
}
中阶(60分)
#include<cstdio>
using namespace std;
long long a,b,i=0;
int main()
{
scanf("%lld%lld",&a,&b);
while(a*i%b!=1) i++;
printf("%lld",i);
return 0;
}
进阶(70分)
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
long long a,b;
scanf("%lld%lld",&a,&b);
long long y=1;
while((b*y+1)%a!=0) y=y+1;
printf("%lld\n",(b*y+1)/a);
return 0;
}
满分解法
可以先了解一下扩展gcd
然后,我们要知道这道题的第一种解法,如果我们假设b的系数是y的话,那么,ax+by=(a,b)。
知道了这个式子,我们可以无线往下推,直到用等式的性质&余数的性质推到b=0。ax=a,x=1。
然后无线回带,就得到了答案。
显然,我们可以用递归来实现。
#include<cstdio>
using namespace std;
long long x,y,m,n,l,a,b,d;
void dg(long long a,long long b,long long &d,long long &x,long long &y)
{
int t;
if(!b) x=1,y=0,d=a;
else dg(b,a%b,d,x,y),t=x,x=y,y=t-a/b*y;
}
int main()
{
scanf("%lld%lld",&a,&b);
dg(a,b,d,x,y);
printf("%d",(x%b+b)%b);
return 0;
}
所以我们可以知道第二种方法,欧拉公式……
但是,我们知道欧拉这个人嘛,公式特别多,所以我找不着了……
所以,下次看到补上来吧。