EXCRT(中国单身狗定理)
Posted llcsblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EXCRT(中国单身狗定理)相关的知识,希望对你有一定的参考价值。
(excrt) ( ext{是用来解决当模数不互质的情况下的普通}crt ext{情况的})
具体见P4777
事实上和(crt)没有什么关系
主要思想是:我们不断的合并两个同余方程,最后合并到只剩一个。
对于方程组
(egin{cases} x equiv b_1 ({ m mod} a_1) \\ xequiv b_2 ({ m mod} a_2) \\ end{cases})
我们考虑合并 这两个同余方程组
我们化为
(egin{cases} x =a_1k_1+b_1\\ x=a_2k_2+b_2 \\ end{cases})
( herefore a_1k_1+b_1=a_2k_2+b_2)
( herefore a_1k_1-a_2k_2=b_2-b_1)
这个可以用(exgcd)求出一组当(a_1k_1-a_2k_2=(a1,a2))时的特解
我们将(x*gcd(a1,a2)/(b_2-b_1))就可以得到原方程的一组解
那么我们可以回代解出(a_1,b_1,a_2,b_2)
然后
我们将(b_2-b_1)作为新的(x),([a_1,a_2])作为新的模数,(a_1k_1-a_2k_2)作为新的余数
我们就成功的合并了两个方程
然后不停的合并下去,最后的(x)就是答案了
代码
/*
@Date : 2018-10-07 11:01:36
@Author : Adscn ([email protected])
@Link : https://www.cnblogs.com/LLCSBlog
*/
#ifdef FASTER
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#endif
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
typedef long long ll;
IL ll getint()
{
RG ll xi=0;
RG char ch=gc;
bool f=0;
while(ch<'0'|ch>'9')ch=='-'?f=1:f,ch=gc;
while(ch>='0'&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
return f?-xi:xi;
}
inline ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1,y=0;
return a;
}
ll gcd=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return gcd;
}
struct node{
ll mod,a;
}last,now;
istream& operator >> (istream&is,node &p)
{
cin>>p.mod>>p.a;
return is;
}
node join(node p,node q)
{
ll x,y;
ll gcd=exgcd(p.mod,q.mod,x,y);
x=(x*(__int128)(q.a-p.a)/gcd)%(q.mod/gcd);
if((q.a-p.a)%gcd)exit(1);
p.a=x*p.mod+p.a;
p.mod=p.mod/gcd*q.mod;
p.a=(p.a%p.mod+p.mod)%p.mod;
return p;
}
int main(void)
{
#ifdef ONLINE_JUDGE
// File("");
#endif
ll n;
cin>>n>>last;
for(int i=2;i<=n;i++)
{
cin>>now;
last=join(last,now);
}
cout<<last.a;
return 0;
}
以上是关于EXCRT(中国单身狗定理)的主要内容,如果未能解决你的问题,请参考以下文章