luoguP1082同余方程
第二道綠題
這次大概真正懂了
看題面:
先了解一下公式?ax≡1(modb)
≡為恒等
這個公式翻譯過來就是一個不定方程
ax+by=1
如果了解擴展歐幾里得就知道這是一道exgcd的模版題//gg說的emmm
那我們先來了解一下gcd和擴展gcd吧(畢竟我本人當初也不會
gcd:
?又稱為輾轉相除法
因為是求最大公約數,很好理解,就不再贅述了,上代碼:
int gcd(a,b){if (b==0)return a;elsereturn gcd(b,a%b);//輾轉相除 }exgcd:
基本思路:對于不全為 0 的非負整數 a,b,gcd(a,b)表示 a,b 的最大公約數,必然存在整數對 x,y ,使得 gcd(a,b)=ax+by
證明:
顯然,b=0時,gcd(a,b)=a,x=1,y=0
當ab!=0時
根據gcd可知:gcd(a,b)=gcd(b,a%b)
我們可以設x,x',y,y' //這里我們把a,b想成未知數,x,y想成常數,雖然較于正常方程來說有點別扭,但是適應一下就很好理解了
這樣:ax+by=gcd(a,b)
bx'+(a%b)y'=gcd(b,a%b)
可得ax+by=bx'+(a%b)y'
我們知道a%b=a-(a/b)*b //這里的式子都是編程里用到的
則ax+by=bx'+ay'-(a/b)*by'
ax+by=ay'+b(x'-(a/b)y')
這樣就可以發現取等的條件了:x=y'&&y=x'-(a/b)y'
如此,求x',y',我們可以設x'',y''
x'=y''&&y'=x''-(a/b)y''
如此一直推下去,我們可以用遞歸來解決
int exgcd(int a,int b,int &x,int &y) {if(b==0){x=1;y=0;return a;}int r=exgcd(b,a%b,x,y);int t=x;x=y;y=t-a/b*y;return r;}這里的b總會推成0,遞歸就結束了
我們現在已經了解了exgcd
現在再看這道題ax+by=1,求x的最小整數解
方程?ax+by=1有解的必要條件是 1%gcd(a,b)=0
那么相應的a,b互質
我們只需要求出ax+by=gcd(a,b)中x的最小整數解就可以了
顯然,這就是一道exgcd的板子題 //然而您需要推出來上面的式子才能發現(。ì _ í。)
等等 可是題目要求的是x為正整數
我們用exgcd求出的x不一定是最小正整數
所以我們要將x+或-b直到x恰好大于0
然后您就切了這道題了!(tql!
#include<cstdio> #include<iostream> typedef long long ll;//為了避免數太大而開了long long,事實證明其實不需要…… using namespace std; ll x,y; void exgcd(ll a,ll b) {if(b==0) {x=1;y=0;return ;}exgcd(b,a%b);ll k=x;x=y;y=k-a/b*y; }//exgcd int main() {ll a,b;scanf("%lld%lld",&a,&b);exgcd(a,b);while(x<0)x+=b;x%=b;//使x為最小整數解printf("%lld",x);return 0; }//本苣蒻第二篇題解祭
//真正理解的第一道綠題祭
//謝謝洛谷題解orz
轉載于:https://www.cnblogs.com/sevenyuanluo/p/9971860.html
總結
以上是生活随笔為你收集整理的luoguP1082同余方程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jmeter工具笔记-Jmeter+in
- 下一篇: 剩余价值率是剩余价值与什么的比率