CRT 中国剩余定理
CRT 中国剩余定理
设
有整数解,解为
证明略 定理不就是用来背的吗
模版:
P1495 【模板】中国剩余定理(CRT)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lxl long long
using namespace std;
lxl a[15],b[15];
int n;
inline lxl exgcd(lxl a,lxl b,lxl &x,lxl &y)
{
if(!b) {x=1,y=0;return a;}
lxl k=exgcd(b,a%b,x,y);
lxl z=x;x=y,y=z-a/b*y;
return k;
}
inline lxl china()
{
lxl M=1,ans=0;
for(int i=1;i<=n;i++)
M*=a[i];
for(int i=1;i<=n;i++)
{
lxl tx,y,Mi=M/a[i];
exgcd(Mi,a[i],tx,y);
ans=(ans+b[i]*Mi*tx)%M;
}
return (ans+M)%M;
}
int main()
{
//freopen("P1495.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i],&b[i]);
printf("%lld\n",china());
return 0;
}
exCRT 扩展中国剩余定理
说是中国剩余定理,但是好像和CRT关系不大。
扩展中国剩余定理就是合并线性同余方程式,解决
先考虑两个同余方程式:
如果不定方程有解,使用扩展欧几里德算法求出一个
则:
于是就把两个同余方程式合并成了一个。同理,将所有方程式按此方法合并,答案为最后的
模版:
P4777 【模板】扩展中国剩余定理(EXCRT)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define lxl long long
#define maxn 100005
using namespace std;
inline lxl times(lxl a,lxl b,lxl mod)
{
lxl ans=0;
while(b>0)
{
if(b%2) ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;
}
inline lxl exgcd(lxl a,lxl b,lxl &x,lxl &y)
{
if(!b) {x=1,y=0;return a;}
lxl k=exgcd(b,a%b,x,y);
lxl z=x;x=y,y=z-a/b*y;
return k;
}
int n;
lxl a[maxn],b[maxn];
int main()
{
//freopen("P4777.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]);
lxl M=a[1],ans=b[1];
for(int i=2;i<=n;i++)
{
lxl a1=M,a2=a[i],bi=(b[i]-ans%a2+a2)%a2,x,y;
lxl g=exgcd(a1,a2,x,y);
a2/=g,bi/=g;
x=times(x,bi,a2);
ans+=M*x;
M*=a[i]/g;
ans=(ans+M)%M;
}
printf("%lld\n",(ans+M)%M);
return 0;
}