关于中国剩余定理及同余方程组求解

Posted lovtolzx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于中国剩余定理及同余方程组求解相关的知识,希望对你有一定的参考价值。

上个月去清北学堂

膜拜牛逼滴 ZHXdalao

他在讲求解同余方程组时说了他个人独创的一种牛逼算法 -----------------------大数翻倍法

说白了就是小学奥赛

例如:

我们在求解一组同余方程组

①x≡3(mod 5)

②x≡6(mod 7)

③x≡11(mod 23)

有些dalao一眼就看出来了 但是对不起 我们需要用计算机求解

至于什么扩欧求解我压根也不讲并且也不会

首先

我们假设 最终解ans=1   每次翻的数res=1

十分明显ans不满足①

那么就让ans翻滚吧  每一次加上res 翻呀翻呀翻呀翻呀翻呀

直到ans=3 可以 那就下一组

可是到了下一组 我想翻得快一些同时维护上面的同余性质 怎末办怎末办

可以考虑把res更新为TA与这个模数的LCM

于是res更新为 5

到了② ans在翻倍同时保持②以前方程的同余性质

这次ans翻成13 同时res更新为35

这时我们可以检验一下 把更新后的ans带入① 依然成立

为什么 ??????????

因为我们每次加上res 实质上是加了前面模数的共同LCM

所以同余性质不变

③同理 ans更新为678 res更新为805

带入同余方程组 依然成立

完美求解   

至于TA的性能 本蒟蒻还没进行过多试验 不过可以提供一道板子题

https://www.luogu.org/problemnew/show/P1495

据说ZHXdalao 用这个方法秒杀所有中国剩余定理的题

好了 不多说了 一言不合上代码

技术分享图片
 1 #pragma GCC optimize(3)
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<cstdlib>
 8 #include<string>
 9 #include<queue>
10 #include<map>
11 #include<stack>
12 #include<list>
13 #include<set>
14 #include<deque>
15 #include<vector>
16 #include<ctime>
17 #define ll long long
18 #define inf 0x7fffffff
19 #define N 500008
20 #define IL inline
21 #define M 1008611
22 #define D double
23 #define ull unsigned long long
24 #define R register
25 using namespace std;
26 template<typename T>void read(T &a)
27 {
28     T x=0,f=1;char ch=getchar();
29     while(!isdigit(ch))
30     {
31         if(ch==-)f=0;ch=getchar();
32     }
33     while(isdigit(ch))
34     {
35         x=(x<<1)+(x<<3)+ch-0;ch=getchar();
36     }
37     a=f?x:-x;
38 }
39 /*-------------OI使我快乐-------------*/
40 ll gcd(ll xi,ll yi){
41     if(xi<yi) swap(xi,yi);
42     ll ri=xi%yi;
43     while(ri){
44         xi=yi;yi=ri;
45         ri=xi%yi;
46     }
47     return yi;
48 }
49 ll n;
50 ll ans=1,res=1;
51 ll num1[20],num2[20];
52 int main()
53 {
54 //    freopen(".in","r",stdin);
55 //    freopen(".out","w",stdout);
56     read(n);
57     for(R ll i=1;i<=n;++i) read(num1[i]),read(num2[i]);
58     for(R ll i=1;i<=n;++i){
59         if(ans%num1[i]!=num2[i])
60          while(ans%num1[i]!=num2[i]) ans+=res;
61         res=res*num1[i]/gcd(res,num1[i]); 
62     }
63     printf("%lld
",ans);
64 //    fclose(stdin);
65 //    fclose(stdout);
66     return 0;
67 }
View Code

若有认为存在版权抄袭问题 请及时与我联络

以上是关于关于中国剩余定理及同余方程组求解的主要内容,如果未能解决你的问题,请参考以下文章

什么叫中国剩余定理

中国剩余定理

请问中国剩余定理是啥?请说的详细点

『线性同余方程和中国剩余定理』

数论之中国剩余定理

中国剩余定理_解一次同余方程组