AcWing 204. 表达整数的奇怪方式 (线性同余方程组)打卡
给定2n个整数a1,a2,…,ana1,a2,…,an和m1,m2,…,mnm1,m2,…,mn,求一个最小的整数x,满足∀i∈[1,n],x≡mi(mod ai)∀i∈[1,n],x≡mi(mod ai)。
输入格式
第1行包含整数n。
第2..n行:每i+1行包含两个整数aiai和mimi,数之间用空格隔开。
输出格式
输出整数x,如果x不存在,则输出-1。
数据范围
1≤ai≤231−11≤ai≤231−1,
0≤mi<ai0≤mi<ai
输入样例:
2
8 7
11 9
输出样例:31
题意:求出同时满足所有式子要求的最小整数x,如果不存在输出-1
思路:首先没说m互相互质,所以这不是中国剩余定理,这是线性同余方程组问题 这里摘抄一位大佬的
中国剩余定理,又名孙子定理o(*≧▽≦)ツ
能求解什么问题呢?
问题:
一堆物品
3个3个分剩2个
5个5个分剩3个
7个7个分剩2个
问这个物品有多少个
解这题,我们需要构造一个答案
我们需要构造这个答案
5*7*inv(5*7, 3) % 3 = 1
3*7*inv(3*7, 5) % 5 = 1
3*5*inv(3*5, 7) % 7 = 1
这3个式子对不对
显然这里就要用到线性同余方程用扩欧来求解
然后两边同乘你需要的数
2 * 5*7*inv(5*7, 3) % 3 = 2
3 * 3*7*inv(3*7, 5) % 5 = 3
2 * 3*5*inv(3*5, 7) % 7 = 2
令
a = 2 * 5*7*inv(5*7, 3)
b = 3 * 3*7*inv(3*7, 5)
c = 2 * 3*5*inv(3*5, 7)
那么
a % 3 = 2
b % 5 = 3
c % 7 = 2
其实答案就是a+b+c
因为
a%5 = a%7 = 0 因为a是5的倍数,也是7的倍数
b%3 = b%7 = 0 因为b是3的倍数,也是7的倍数
c%3 = c%5 = 0 因为c是3的倍数,也是5的倍数
所以
(a + b + c) % 3 = (a % 3) + (b % 3) + (c % 3) = 2 + 0 + 0 = 2
(a + b + c) % 5 = (a % 5) + (b % 5) + (c % 5) = 0 + 3 + 0 = 3
(a + b + c) % 7 = (a % 7) + (b % 7) + (c % 7) = 0 + 0 + 2 = 2
你看你看,答案是不是a+b+c(。・ω・)ノ゙,完全满足题意
但是答案,不只一个,有无穷个,每105个就是一个答案(105 = 3 * 5 * 7)
根据计算,答案等于233,233%105 = 23
如果题目问你最小的那个答案,那就是23了
结论:因为我要同时满足多个式子的要求,那么我们来一个一个来满足,当前的余数我就用其他数来拼凑
因为是其他数的乘积,那么其他数mod的话都会等于0,然后只有当前数会有余数,这样就能得出一个其他所有数mod等于0,满足当前数余数要求的数了
然后我们用这个方法给每个数都求一个这样的数,然后求和,那么就能满足所有数的要求了,当然这只限于两两互质情况
不互质的中国剩余定理 - 线性同余方程组
首先为什么要互质呢
因为如果化简成最简质因子的话,如果有相同质因子,那么有可能会mod成0,那么我们也不能借用来获取自己想要的数了
如
{
x = 2 mod 4
x = 3 mod 6
x = 4 mod 8
}
6*8%4 = 0 ,所以就不行了
这里我们要用线性同余方程组,来两两合并,最后化简成一个来得出答案

然后我们就可以得出推导式
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#define LL long long
using namespace std;
LL m[],r[];
void ex_gcd(LL a,LL b,LL &d,LL &x,LL &y)
{
if(b==){ x=;y=;d=a;return ;}
ex_gcd(b,a%b,d,y,x); y-=x*(a/b);
}
LL gcd(LL a,LL b)
{
return b==?a:gcd(b,a%b);
}
LL ex_CRT(int n)
{
LL a,b,c,c1,c2,x,y,d,N;
a=m[]; c1=r[];
for(int i=;i<=n;i++){
b=m[i];c2=r[i]; c=c2-c1;
ex_gcd(a,b,d,x,y);
if(c%d) return -;
LL b1=b/d;//转移式
x=((c/d*x)%b1+b1)%b1;//
c1=a*x+c1; a=a*b1;//
}
/*if(c1==0){
c1=1; for(int i=1;i<=n;i++) c1=c1*m[i]/gcd(c1,m[i]); //如果题目要求要正整数,那么加上一个所有数的最小公倍数
}*/
return c1;
}
int main()
{
int T,n,Case=;
scanf("%d",&n); for(int i=;i<=n;i++) scanf("%lld%lld",&m[i],&r[i]);
// LL c1=1; for(int i=1;i<=n;i++) c1=c1*m[i]/gcd(c1,m[i]);
printf("%lld\n",ex_CRT(n));
return ;
}
AcWing 204. 表达整数的奇怪方式 (线性同余方程组)打卡的更多相关文章
- AcWing 204. 表达整数的奇怪方式 / Strange Way To Express Integers
我作为一个初中蒟蒻,听y大视频听了5遍还不懂,快哭了.然后终于(好像)搞懂,写成题解加深一下记忆... 将式子等价转换 对于每两个式子(我们考虑将其合并): \(x \equiv a_1 \%\ m_ ...
- AcWing 204. 表达整数的奇怪方式
#include<bits/stdc++.h> using namespace std; typedef long long LL; LL exgcd(LL a,LL b,LL & ...
- HDU3579:Hello Kiki(解一元线性同余方程组)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3579 题目解析:求一元线性同余方程组的最小解X,需要注意的是如果X等于0,需要加上方程组通解的整数区间lc ...
- HDU1573:X问题(解一元线性同余方程组)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1573 题目解析;HDU就是坑,就是因为n,m定义成了__int64就WAY,改成int就A了,无语. 这题 ...
- HDU1573 X问题【一元线性同余方程组】
题目链接: http://acm.hdu.edu.cn/showproblem.php? pid=1573 题目大意: 求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X ...
- AcWing 203. 同余方程 (线性同余方程)打卡
求关于x的同余方程 ax ≡ 1(mod b) 的最小正整数解. 输入格式输入只有一行,包含两个正整数a,b,用一个空格隔开. 输出格式输出只有一行,包含一个正整数x,表示最小正整数解. 输入数据保证 ...
- poj3708(公式化简+大数进制装换+线性同余方程组)
刚看到这个题目,有点被吓到,毕竟自己这么弱. 分析了很久,然后发现m,k都可以唯一的用d进制表示.也就是用一个ai,和很多个bi唯一构成. 这点就是解题的关键了. 之后可以发现每次调用函数f(x),相 ...
- Acwing-204-表达整数的奇怪方式(扩展中国剩余定理)
链接: https://www.acwing.com/problem/content/206/ 题意: 给定2n个整数a1,a2,-,an和m1,m2,-,mn,求一个最小的非负整数x,满足∀i∈[1 ...
- POJ2891:Strange Way to Express Integers(解一元线性同余方程组)
写一下自己的理解,下面附上转载的:若a==b(modk);//这里的==指的是同余,我用=表示相等(a%k=b)a-b=kt(t为整数)以前理解的错误思想:以前认为上面的形式+(a-tb=k)也是成立 ...
随机推荐
- UNP学习第五章
一.概述 想要写一个完整的TCP客户-服务器程序例子,有下面功能的回射服务器 1.客户从标准输入读一行文本,写到服务器上: 2.服务器从网络输入读此行,并回射给客户: 3.客户读此回射行并写到标准输出 ...
- springmvc缓存 - cache
前几篇文章已经搭建了一个基本的springmvc demo,现在我们来完善下. 相信大家写程序的时候都接触过缓存的概念,也都知道,数据量大的时候缓存对于提高效率是很显著的.而缓存一般包括前台静态 ...
- NIO模型学习笔记
NIO模型学习笔记 简介 Non-blocking I/O 或New I/O 自JDK1.4开始使用 应用场景:高并发网络服务器支持 概念理解 模型:对事物共性的抽象 编程模型:对编程共性的抽象 BI ...
- 项目集成swagger,并暴露指定端点给swagger
项目集成swagger 一:思考: 1.swagger解决了我们什么问题? 传统开发中,我们在开发完成一个接口后,为了测试我们的接口,我们通常会编写单元测试,以测试我们的接口的可用性,或者用postm ...
- 一个python练习
问题描述: 有一对兔子,每隔3个月就生一对兔子,生下来的兔子也是每隔3个月就生兔子,以此类推... 用python模拟出来: #!/usr/bin/python3 import random impo ...
- inline-block 导致元素下沉 解决方法添加vertical-align:middle属性
<div class="layui-input-block"> <input name="username" lay-verify=" ...
- Oracle之Group by和Having-----转了
在介绍GROUP BY 和 HAVING 子句前,我们必需先讲讲sql语言中一种特殊的函数:聚合函数,例如SUM, COUNT, MAX, AVG等.这些函数和其它函数的根本区别就是它们一般作用在多条 ...
- 【lua学习笔记】--- 数据类型
print("hello world!") --[注释方法]-- 单行注释 对应C# //--[[ 多行注释 /* 对应C# */]]-- -- [数据类型]--1 nil 空值 ...
- LINUX 安装PHP GD库遇到的坑
本文借鉴:https://www.cnblogs.com/gaohj/p/3152646.html linux下为php添加GD库的步骤如下: 一.下载 gd-.tar.gz http://www.b ...
- js中构造函数的原型添加成员的两种方式
首先,js中给原型对象添加属性和方法. 方式一:对象的动态特效 给原型对象添加成员 语法:构造函数.prototype.方法名=function (){ } 方式二:替换原型对象(不是覆盖,而是替换, ...