关于中国剩余定理及同余方程组求解
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 }
若有认为存在版权抄袭问题 请及时与我联络
以上是关于关于中国剩余定理及同余方程组求解的主要内容,如果未能解决你的问题,请参考以下文章