日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数论相关:同余方程与同余方程组的解法

發布時間:2025/3/15 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数论相关:同余方程与同余方程组的解法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

同余方程

形如 \(ax \equiv b \pmod n\) 的式子稱為線性同余方程。對于這樣的式子有解的充要條件是 \(gcd(a,n) \mid b\) .

于是擴展gcd求解
將原方程化為一次不定方程 \(ax+ny = b\) .
利用擴展歐幾里得算法求解不定方程 $ ax + ny = b$ 的整數解的求解全過程,步驟如下:

1、先計算 \(gcd(a,n)\),若 \(b\) 不能被 \(gcd(a,n)\) 整除,則方程無整數解;否則,在方程右邊除以 \(b/gcd(a,n)\),記 得到新的不定方程 \(ax_0 + ny_0 = gcd(a,n)\).

2、利用擴展歐幾里德算法求出方程 $ax_0 + ny_0 = gcd(a, b) $的一組整數解 \(x_0\) , \(y_0\)

3、根據數論中的相關定理,記 \(k=b/gcd(a,n)\),可得方程 \(ax + ny = b\) 的所有整數解為:

\[ x = k*x_0 + n/gcd(a,n)* t \\ y =k* y_0 –a/gcd(a,n)* t \\ (t=0,1,2,……)\]
調整得到關于 \(x\) 的正整數解
注意因為解有多個,而我們要求最優解(正整數中最小的),所以 \((x+=n/gcd(a,n)\%(n/gcd(a,n))\);
加法是為了保證正數,取模是為了最小

青蛙的約會

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <cmath> using namespace std; long long init(){long long rv=0,fh=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-') fh=-1;c=getchar();}while(c>='0'&&c<='9'){rv=(rv<<1)+(rv<<3)+c-'0';c=getchar();}return fh*rv; } long long x,y,m,n,l; long long exgcd(long long a,long long b,long long &x,long long &y){if(b==0){x=1;y=0;return a;}long long t=exgcd(b,a%b,y,x);y-=(a/b)*x;return t; } int main(){freopen("in.txt","r",stdin);x=init();y=init();m=init();n=init();l=init(); if(m - n< 0) swap(m, n), swap(x, y);long long a=0,b=0;long long t=exgcd(m-n,l,a,b);if(n==m||(x-y)%t!=0){printf("Impossible");return 0;}(a*=(y-x)/t)%=(l/t);(a+=l)%=(l/t);//以保證最優解cout<<a;fclose(stdin);return 0; }

exgcd可以用來求逆元

\(ax \equiv 1 \pmod n\) 已知 \(a\) , \(n\)\(x\)
因為 \(n\) 是個素數,所以 \(gcd(a,n)==1\) ;
原方程可化為 \(ax \equiv gcd(a,n) \pmod n\)
用exgcd求解即可。

同余方程組

\(x\%p_1 = b_1\)
\(x\%p_2 = b_2\)
\(x\%p_3 = b_3\)
\(x\%p_4 = b_4\)
\(x\) 的最小正整數解
小范圍數據直接枚舉

對于模數互質的情況,使用中國剩余定理(CRT)
\(m=p_1p_2p_3 \ldots p_n\)
構造出
//定義 \(ni(k,p)\)\(k\) 在模 \(p\) 意義下逆元
\[x = (m/p_1*ni(m/p_1, p_1)*a1 + \ldots) \% m\]
CRT求解同余方程組

#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> using namespace std; long long a1,a2,a3,a4,b1,b2,b3,b4; long long m; long long exgcd(long long a,long long b,long long &x,long long &y){if(!b){x=1;y=0;return a;}long long t=exgcd(b,a%b,y,x);y-=a/b*x;return t; } long long ni(long long a,long long b){long long x=0,y=0;long long t=exgcd(a,b,x,y);if(t!=1) return -1;else return((x+b)%b); } int main(){freopen("in.txt","r",stdin);cin>>a1>>b1>>a2>>b2>>a3>>b3>>a4>>b4;m=a1*a2*a3*a4;cout<<(m/a1*ni(m/a1,a1)*b1+m/a2*ni(m/a2,a2)*b2+m/a3*ni(m/a3,a3)*b3+m/a4*ni(m/a4,a4)*b4)%m;fclose(stdin);return 0; }

對于一般情況采用exgcd兩兩合并,
\(x+a_1k_1=b_1\)
\(x+k_2a_2=b_2\)
\(a_1k_1-k_2a_2=b_1-b_2\)
$t=exgcd(a_1,-a_2,k_1,k_2) $ 實際上 \(-a_2\) 可以寫作 \(a_2\)
合并:
\(k_1=(k_1*(b_1-b_2)/t)\%a2\); //此處是模 \(a_2\) ,因為可以看成是模 \(a_2\)意義下的同余方程
\(b_1-=a_1*k_1\) // \(b_1\) 就是原式中的 \(x\)
\(a_1=a_1/t*a_2\) //把 $ a_1\(變成\)lcm(a1,a2)$
\(b_1\%=a_1\) //把 \(b_1\) 調整至新式子的B
此時就把兩個式子合并為了一個,待所有的都合并完后,結果就是 \(b_1\) 調整好的最小正整數 \((b_1+=a_1)\%=a_1\)

#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <cstdlib> #define LL long long using namespace std; LL init(){LL rv=0,fh=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-') fh=-1;c=getchar();}while(c>='0'&&c<='9'){rv=(rv<<1)+(rv<<3)+c-'0';c=getchar();}return rv*fh; } LL a,b,a1,b1; LL exgcd(LL a,LL b,LL &x,LL &y){if(!b){x=1;y=0;return a;}LL t=exgcd(b,a%b,y,x);y-=a/b*x;return t; } int main(){freopen("in.txt","r",stdin);a=init();b=init();for(int i=1;i<=3;i++){a1=init();b1=init();LL x=0,y=0;LL t=exgcd(a,a1,x,y);x=(x*(b-b1)/t)%a1;b-=a*x;a=a/t*a1;b%=a;}(b+=a)%=a;cout<<b;fclose(stdin);return 0; }

求逆元

\(ax \equiv 1 \pmod n\)
逆元存在的充要條件是\(gcd(a,n)==1\);
一般采用exgcd求逆元,若p是質數,也可使用費馬小定理,快速冪
模質數 \(P\) 意義下

\(1! \sim n!\)

先用快速冪處理出 \(n!^{-1}\),并預處理出來,\(1! \sim n!\),那么
\[n^{-1} = n!^{-1} * (n - 1)!\]
\[(n-1)!^{-1} = n!^{-1} * n\]
由此遞推即可

從 $1 \sim n $

此方法不需要求階乘,代碼簡單
首先 \(1^{-1} = 1\pmod p\)
設 $p = k * i + r $, \(1 < i < p, r < i\)
所以 \(k * i + r \equiv 0 \pmod p\)
所有兩邊同乘以 \(i^{-1}*r^{-1}\)
\[k * r^{-1} + i^{-1} \equiv 0 \pmod p\\ i^{-1} \equiv -k * r^{-1} \pmod p\\ i^{-1} \equiv -\lfloor p/r \rfloor * ( p\mod i)^{-1} \]

N[i] = (p -p / i) * N[p % i] %p;

轉載于:https://www.cnblogs.com/Mr-WolframsMgcBox/p/7868283.html

總結

以上是生活随笔為你收集整理的数论相关:同余方程与同余方程组的解法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。