中国剩余定理
参考资料
简介
中国剩余定理 (Chinese Remainder Theorem,CRT) 可求解如下形式的一元线性同余方程组:
其中 两两互质。
扩展中国剩余定理(EXCRT)可以解决模数不互质的情况。
例题
自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。举个例子,假如有 头母猪,如果建了 个猪圈,剩下 头猪就没有地方安家了。如果建造了 个猪圈,但是仍然有 头猪没有地方去,然后如果建造了 个猪圈,还有 头没有地方去。你作为曹总的私人秘书理所当然要将准确的猪数报给曹总,你该怎么办?代码(3)
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
tuple<ll,ll,ll> exgcd(ll a,ll b)
{
if(!b)return {a,1,0};
auto [g,x,y]=exgcd(b,a%b);
return {g,y,x-a/b*y};
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
vector<pair<ll,ll>> a(n);
__int128 sum=1;
for(auto &[u,v]:a)
{
cin>>u>>v;
sum*=u;
}
__int128 ans=0;
for(auto [u,v]:a)
{
ll k=sum/u;
auto [g,x,y]=exgcd(k,u);
ans=(ans+k*x%sum*v%sum+sum)%sum;
}
cout<<ll(ans)<<'\n';
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll=long long;
tuple<ll,ll,ll> exgcd(ll a,ll b)
{
if(!b)return {a,1,0};
auto [g,x,y]=exgcd(b,a%b);
return {g,y,x-a/b*y};
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
__int128 ans=0,sum=1;
while(n--)
{
ll a,b;
cin>>a>>b;
auto [g,x,y]=exgcd(sum,a);
ans-=(ans-b)/g*x*sum;
sum*=a/g;
ans=(ans%sum+sum)%sum;
}
cout<<ll(ans)<<'\n';
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll=long long;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
ll ans=0,sum=1;
while(n--)
{
ll a,b;
cin>>a>>b;
while(ans%a!=b)ans+=sum;
sum*=a;
}
cout<<ans<<'\n';
return 0;
}
给定 组非负整数 ,求解关于 的方程组的最小非负整数解。
代码(1)
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
tuple<ll,ll,ll> exgcd(ll a,ll b)
{
if(!b)return {a,1,0};
auto [g,x,y]=exgcd(b,a%b);
return {g,y,x-a/b*y};
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
__int128 ans=0,sum=1;
while(n--)
{
ll a,b;
cin>>a>>b;
auto [g,x,y]=exgcd(sum,a);
ans-=(ans-b)/g*x*sum;
sum*=a/g;
ans=(ans%sum+sum)%sum;
}
cout<<ll(ans)<<'\n';
return 0;
}