中国剩余定理模板
/*中國剩余定理簡單解釋:定理:如果a%b=c 那么(a+kb)%b=c首先看一個簡單例子:對于x%3=2,x%5=3,x%7=2,求解x(最小)令m[i]=3,5,7 a[i]=2,3,2;我們假設n1%3=2,但是又要滿足另外兩個方程的解,那么n1必須是5,7的倍數同理n2%3=2且n2必須是3,7的倍數,n3%7=2且n3必須是3,5的倍數那么(n1+n2+n3)就是滿足這三個同余方程的一個解因此x=(n1+n2+n3)%M那么如何求n1,n2,n3呢?可通過歐幾里得算法求解令M=LCD(m[i])即這三個數的最小公倍數,又因為它們互質所以M=m[i]*m[2]*m[3];Ni=M/m[i],那么ni=Ni*t使得Ni*t%m[i]=a[i]得到方程Ni*t+m[i]*y=a[i],t,y為要求的變量ni=Ni*t*a[i],因為通過歐幾里得算出來的t只滿足Ni*t%m[i]=1,因此還需要乘以a[i]*/#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//歐幾里得算法
__int64 extend_euclid(__int64 a,__int64 b,__int64 &x,__int64 &y)
{if(b==0){x=1;y=0;return a;}__int64 d = extend_euclid(b,a%b,x,y);__int64 t = x;x=y;y=t-a/b*y;return d;
}
//中國剩余定理求解x=a[i](mod(m[i]))---也就是x%m[i]=a[i],只針對m[i]互質情況
//參數len,同余方程的個數,m[i],a[i]從1開始,int類型根據題意更改
__int64 cnt(int len,__int64 m[],__int64 a[])
{__int64 M = 1,ans = 0;for(int i=1;i<=len;i++)M*=m[i];__int64 x,y;for(int i=1;i<=len;i++){__int64 Ni = M/m[i];extend_euclid(Ni,m[i],x,y);x=(x%m[i]+m[i])%m[i];//保證x為最小的正數解ans=(ans+x*a[i]*Ni)%M;}if(ans<0)ans=ans+M;return ans;
}
int main()
{int n;__int64 m[10],a[10];scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%I64d%I64d",&m[i],&a[i]);printf("%I64d\n",cnt(n,m,a));return 0;
}
?
轉載于:https://www.cnblogs.com/wt20/p/5775218.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
- 上一篇: [ An Ac a Day ^_^ ]
- 下一篇: 不完整类型(partial type)