题目描述
求关于 xx 的同余方程 a x \equiv a \pmod {1}ax≡a(mod1) 的最小正整数解。
输入输出格式
输入格式:一行,包含两个正整数 a,ba,b ,用一个空格隔开。
一个正整数 x_0x0 ,即最小正整数解。输入数据保证一定有解。
思路
一道模板题。
首先对于ax ≡ 1 (mod b); 观察数据范围可以发现b≥2,所以转化成 ax mod b=1。从mod的定义中我们可以看出原方程就是ax-by=1(y是整数)
因为一定有解,然后由裴蜀定理可以知道gcd(a,b)|1,即gcd(a,b)=1,得证a,b互质。
//拓展欧几里德 1.求解不定方程a*x+b*y==gcd(a,b); 先给个解法推导吧: ∵a=[a/b]*b+a%b; 又∵欧几里得知:gcd(a,b)==gcd(b,a%b); ∴([a/b]*b+a%b)*x+b*y=gcd(a,b); ∴[a/b]*b*x+(a%b)*x+b*y=gcd(a,b); ∴b*([a/b]*x+y)+(a%b)*x=gcd(b,a%b); 看到这里,我们不难发现: 令:a'=b,x'=[a/b]*x+y,b'=a%b,y'=x; 整理后原式又变成了:a'*x'+b'*y'==gcd(a',b'); 当当当当!!!!!可以递归了,求最小解代码见下: #define ll long long ........ void ogcd(ll a,ll b,ll &x,ll &y){ if(!b) x=1,y=0; else{ ogcd(b,a%b,y,x); y-=(a/b)*x; } } 当然解虽然最小,有可能是负数,所以只要加个b/gcd(a,b)再模上b/gcd(a,b)就行了;
2.同余方程ax≡b(mod c)的求解: (1)有解条件: 当且仅当:gcd(a,c)|b;(懒得证了) 即:b能被gcd(a,c)整除; (2)例:洛谷1082 同余方程ax≡1(mod b): 分析: 先根据有解的必要条件,显而易见: gcd(a,b)|1 ==> gcd(a,b)==1; 题目给的a,b一定互质; 再化开:(a*x)%b==1%b ==> (a*x-1)%b==0 ==> a*x==k*b+1 (k∈Z) ==> a*x-k*b==1 ==> a*x-k*b==gcd(a,b) 是不是和上面的1.一样了?
上面两段代码框是转载的。
#include <cstdio> #include <iostream> using namespace std; void ogcd(long long a,long long b,long long &x,long long &y) { if(!b) x=1,y=0; else { ogcd(b,a%b,y,x); y-=(a/b)*x; } } int main() { long long a,b,x,y; scanf("%lld%lld",&a,&b); ogcd(a,b,x,y); printf("%lld",(x+b)%b); return 0; }