Crt and ExCrt
\(Crt\)
求解不定方程组
设\(M=\prod\limits_i^nm_i\)
\(M_i=\frac{M}{m_i}=\prod\limits_{k,k\neq i}^nm_k\)
\(t_i\)为\(M_i\)在模\(m_i\)时的逆元
先上结论 通解为\(\sum\limits_i^na_iM_it_i mod LCM(m_i)\)
证明:
对于方程组中第\(i\)个方程考虑
\(\because M_k(k\neq i) mod m_i=0\)
\(\therefore \sum\limits_{k,k\neq i}^na_kM_kt_k\equiv0 (mod m_i)\)
又\(\because t_iM_i\equiv1 (mod m_i)\)
\(\therefore a_iM_it_i\equiv a_i (mod m_i)\)
$\therefore \sum\limits_i^na_iM_it_i\equiv a_i (mod m_i) $
解合法
得证,通解为\(\sum\limits_i^na_iM_it_i mod LCM(m_i)\)
void exgcd(int a,int b,int &x,int &y)
{
if(b==0){ x=1; y=0; return;}
exgcd(b,a%b,x,y);
int tp=x;
x=y; y=tp-a/b*y;
}
int china()
{
int ans=0,lcm=1,x,y;
for(int i=1;i<=k;++i) lcm*=b[i];
for(int i=1;i<=k;++i)
{
int tp=lcm/b[i];
exgcd(tp,b[i],x,y);//求逆元
x=(x%b[i]+b[i])%b[i];//x要为最小非负整数解
ans=(ans+tp*x*a[i])%lcm;
}
return (ans+lcm)%lcm;
}
ExCrt
扩展中国剩余定理解决的是\(m_i\)不互质的问题
不再是宏观上直接构造一个通解,因为它的通解无法直接用公式表示
用归纳法,考虑前\(k-1\)个方程的通解为\(x(mod M), M=LCM(m_1到m_{k-1})\)
我们为了符合第\(k\)个方程,需要加一些数,但为了保证前\(k-1\)个方程仍然成立,所以只能加若干倍的\(M\),也就是说找到\(x+t*M\equiv a_k(mod m_k)\)
上式整理得\(t*M\equiv a_k-x(mod m_k)\)
可以用扩展欧几里得求解,若同余方程无解则整个方程组无解
否则新的解为\(x+t*M(mod LCM(M,m_k))\)
有一些细节对代码解释
lt exgcd(lt a,lt b,lt &x,lt &y)
{
if(b==0){x=1;y=0;return a;}
lt gcd=exgcd(b,a%b,x,y);
lt tp=x;
x=y; y=tp-a/b*y;
return gcd;
}
lt excrt()
{
lt x,y,k;
lt M=bi[1],ans=ai[1];//一开始赋为初始值
for(int i=2;i<=n;i++)
{
lt a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;//注意取模保证是正数
lt gcd=exgcd(a,b,x,y),bg=b/gcd;//t*M-y*mk=gcd,gcd为M和mk的gcd
if(c%gcd!=0) return -1; //因为求解是根据gcd而不是c,所以还要乘倍数,如果不是倍数证明无解
x=mul(x,c/gcd,bg);//将x乘倍数,这里取模mk/gcd的原因是x(也就是t)还要乘M,乘M之后不能超过LCM(M,mk),也就是不能超过M*m/gcd,所以这里直接对m/gcd取模即可
ans+=x*M;//答案更新
M*=bg;//模数更新
ans=(ans%M+M)%M;//处处取模小心负数
}
return (ans%M+M)%M;
}
原文地址:https://www.cnblogs.com/Liuz8848/p/11372787.html
- 由索引节点(inode)爆满引发的问题
- As3.0中的位图(Bitmap/BitmapData)编程
- Mesos+Zookeeper+Marathon的Docker管理平台部署记录(2)--负载均衡marathon-lb
- Docker集群管理工具-Kubernetes部署记录
- AS3:小游戏“贪吃蛇”的实现
- 超实用的8个Linux命令行性能监测工具
- 用javascript替换URL中的参数值
- Gitblit版本服务器环境部署记录
- HDK扩展自定义VEX函数print
- AsyncTask和Handler对比
- sql初始化XML操作
- 给你一根杠杆,撬起万亿的小程序红利市场!
- Flash/Flex学习笔记(43):动量守恒与能量守恒
- Flash/Flex学习笔记(57):实用技巧
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Mybatis中#{}与${}的区别
- POI合并单元格
- Centos7.x安装Docker
- 实在是妙啊!Java中强软虚弱引用,居然还能这样去操作
- 数据库连接池引起的FullGC问题,看我如何一步步排查、分析、解决
- Swift 数组dropFirst方法
- Swift 类方法和实例方法
- 我从未见过的牛逼解说方式!Redis五种数据结构,看一遍就懂了
- Swift 动态创建ViewController
- Office 文档解析 文档格式和协议
- 查看centos 7里敏感信息的常用命令(未完)
- C# dotnet 使用 FileStream 随机文件读写
- datables之加载数据时显示进度条
- 这几种常见的“分布式锁”写法,搞懂再也不怕面试官,安排
- C# 8.0 文件长度 Bytes 字节转 KB 等单位字符串