AcWing 204. 表达整数的奇怪方式 / Strange Way To Express Integers
我作为一个初中蒟蒻,听y大视频听了5遍还不懂,快哭了。然后终于(好像)搞懂,写成题解加深一下记忆...
将式子等价转换
对于每两个式子(我们考虑将其合并):
\(x \equiv a_1 \%\ m_1\)
\(x \equiv a_2 \%\ m_2\)
则有:
\(x = k_1 * a_1 + m_1\)
\(x = k_2 * a_2 + m_2\)
进一步:
\(k_1 * a_1 + m_1 = k_2 * a_2 + m_2\)
移项:
\(k_1 * a_1 - k_2 * a_2 = m_2 - m_1\)
也就是:
① \(k_1 * a_1 + k_2 * (-a_2) = m_2 - m_1\)
也就是我们需要找到一个最小的\(k_1, k_2\),使得等式成立(因为要求\(x\)最小,而\(a\)和\(m\)都是正数)。
用扩展欧几里得算法找出一组解
我们已知\(a_1,m_1,a_2,m_2\),可以用扩展欧几里得算法算出一个\(k'_1, k'_2\)使得:
\(k'_1 * a_1 + k'_2 * (-a_1) = gcd(a_1, -a_2)\)
无解判断:
若\(gcd(a_1, -a_2) \nmid m_2 - m_1\),则无解。
我们设\(d = gcd(a_1, -a_2),y = \frac{(m_2 - m_1)}{d}\)
承接上文,我们只需让\(k_1, k_2\)分别扩大\(y\)倍,则可以找到一个\(k_1, k_2\)满足①式:
\(k_1 = k'_1 * y, k_2 = k'_2 * y\)
找到最小正整数解
我们知道一个性质:
②\(k_1 = k_1 + k *\frac{a_2}{d}\)
\(k_2 = k_2 + k *\frac{a_1}{d}\)
\(k\)为任意整数,这时新的\(k_1, k_2\)仍满足①式。
证明:
将新的\(k_1, k_2\)带入式子得:
\((k_1+k*\frac{a_2}{d})*a_1+(k_2+k*\frac{a_1}{d})*(-a_2)=m_2-m_1\)
拆出来:
\(k_1*a_1+k*\frac{a_2*a_1}{d}+k_2*(-a_2)+k*\frac{a_1*(-a_2)}{d}=m_2-m_1\)
交换一下顺序,把负号拆出来:
\(k_1*a_1+k_2*(-a_2)+k*\frac{a_2 * a_1}{d}-k*\frac{a_1 * a_2}{d}=m_2-m_1\)
那个同加同减可以消掉:
\(k_1*a_1+k_2*(-a_2)=m_2-m_1\)
这个式子和①是一样的,因①成立,故此式也成立。
要找一个最小的非负整数解,我们只需要让
\(k_1 = k_1 \%\ abs(\frac{a_2}{d})\)
\(k_2 = k_2 \%\ abs(\frac{a_1}{d})\)
即可找到当前最小的\(k_1, k_2\)的解,即此时的\(k\)为\(0\)。
\(Q\):此处为什么要取绝对值呢
\(A\):因为不知道\(\frac{a_2}{d}\)的正负性,我们在原基础上要尽量减多个\(abs(\frac{a_2}{d})\),使其为正整数且最小。
等效替代:
由②式带入
新的\(x\)为:
\(x = (k_1 + k * \frac{a_2}{d}) * a_1 + m_1\)
\(= k_1 * a_1 + m_1 + k * \frac{a_2 * a_1}{d}\)
\(= k_1 * a_1 + m_1 + k * lcm(a_1, a_2)\) ③
\(Q\):这里,\(k\)都为\(0\)了,为什么还要算呢?
\(A\):因为这只是前两个式子得最小\(k\),有可能遇到下一个式子后面被迫要扩大
在③中,我们设\(a_0 = lcm(a_1, a_2), m_0 = k_1 * a_1 + m_1\)
那么:
③ $ = k * a_0 + m_0$
这个形式与一开始我们分解的形式是不是特别像呢?
没错!假设之后又来了一个\(a_3, m_3\)
我们只需要继续找:
\(x = k * a_0 + m_0 = k_3 * (-a_3) + m_3\),那么问题又回到了第一步。
总结
我们的做法相当于每次考虑合并两个式子,将这\(n\)个式子合并\(n - 1\)次后变为一个式子。最后剩下的式子就满足我们的答案。
注意:
\(lcm(a_1, a_2)\)和\(\% \frac{a_2}{d}\),需要取绝对值。又因为\(d = gcd(a_1, -a_2)\),我们不知道\(a_1\)的正负性(可能是上一步推过来的)。
\(\% \frac{a_2}{d}\),需要取绝对值, 膜负数的话,不会取到正解;
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long LL;
int n;
LL exgcd(LL a, LL b, LL &x, LL &y){if(b == 0){x = 1, y = 0;return a;}LL d = exgcd(b, a % b, y, x);y -= a / b * x;return d;
}
LL inline mod(LL a, LL b){return ((a % b) + b) % b;
}
int main(){scanf("%d", &n);LL a1, m1;scanf("%lld%lld", &a1, &m1);for(int i = 1; i < n; i++){LL a2, m2, k1, k2;scanf("%lld%lld", &a2, &m2);LL d = exgcd(a1, -a2, k1, k2);if((m2 - m1) % d){ puts("-1"); return 0; }k1 = mod(k1 * (m2 - m1) / d, abs(a2 / d));m1 = k1 * a1 + m1;a1 = abs(a1 / d * a2);}printf("%lld\n", m1);return 0;
}
转载于:https://www.cnblogs.com/dmoransky/p/11382381.html
AcWing 204. 表达整数的奇怪方式 / Strange Way To Express Integers相关推荐
- AcWing 204. 表达整数的奇怪方式
这道题我第一眼居然想着用二分法做,结果,还是不满足二分条件. WA代码如下 #include<iostream>using namespace std;const int N=30;int ...
- 204. 表达整数的奇怪方式(exgcd,,,数学推导,借助中国剩余定理)
204. 表达整数的奇怪方式 题意: y总的笔记 墨染空大佬的 题解%%%%% AC # include <bits/stdc++.h> using namespace std; type ...
- 数论练习1 ( 曹冲养猪 + [POJ 2891]Strange Way to Express Integers + 乘法逆元【带证明】)
虽然作业还没有做完,但是我还是放不下它,对此,我只想说: 今天你对作业爱理不理,明天它就让你补到飞起 DP先放放,我们要雨露均沾 练习上手:乘法逆元 题目 题解 代码实现 曹冲养猪?(互质的中国剩余定 ...
- 【poj 2891】Strange Way to Express Integers(数论--拓展欧几里德 求解同余方程组 模版题)...
题意:Elina看一本刘汝佳的书(O_O*),里面介绍了一种奇怪的方法表示一个非负整数 m .也就是有 k 对 ( ai , ri ) 可以这样表示--m%ai=ri.问 m 的最小值. 解法:拓展欧 ...
- [POJ2891] Strange Way to Express Integers
题目描述 FJ正在读佳佳写的一本书,书中描述一种表示非负整数的方法:选择k个不同的正整数a1,a2,-,ak,对于某个整数m分别对ai求余对应整数ri,如果适当选择a1,a2,-,ak,那么整数m可由 ...
- 【poj2891】 Strange Way to Express Integers
poj.org/problem?id=2891 (题目链接) 题意:求解线性同余方程组,不保证模数一定两两互质. Solotion 用exgcd将俩个同余方程合并成一个 如合并n%M=R,n%m=r ...
- poj 2891 Strange Way to Express Integers 2012-09-05
http://poj.org/problem?id=2891 解线性模方程组. 比较坑爹,数据比较大,很容易溢出. 1 Program poj2891; 2 3 var m:int64; 4 5 a, ...
- POJ2891 Strange Way to Express Integers【扩展中国剩余定理】
题目大意 就是模板...没啥好说的 思路 因为模数不互质,所以直接中国剩余定理肯定是不对的 然后就考虑怎么合并两个同余方程 \(ans = a_1 + x_1 * m_1 = a_2 + x_2 * ...
- poj-2891(Strange Way to Express Integers)--中国剩余定理扩展欧几里得
题意:找到一个m,使得m%ai=ri,并且这个m最小 m = a1*x + r1; m = a2*y + r2; 可得:a1*x - a2*y = r2 - r1 可得:a1*x ≡ r2-r1(mo ...
最新文章
- Go 知识点(01)— 主协程与子协程执行顺序
- 迁移学习与跨域推荐,以及解决跨域推荐的方法
- 前端工程化工具Fekit分析
- 【 FPGA 】特定情况下消除不稳定态的方法
- Win10下IIS配置图解、MVC项目发布图解、IIS添加网站图解
- 如何写出健壮的代码?
- 邮件系统之webmail
- 在VS Code中直接调试Web程序,是怎样一种体验?
- SpringBoot集成thymeleaf增删改查示例
- 优化算法笔记|飞蛾扑火优化算法理解及实现
- 15 张图, 把TCP/IP 讲得一清二楚!
- 高通最强芯片855发布!AI性能比华为苹果翻倍,商用5G,标配屏下指纹
- 天河二号计算机是微型计算机,计算机二级考试真题-PPT-天河二号超级计算机
- 通过这18000个Python项目对比,并从中精选出 45 个值得学习的!
- 继电器触点RC吸收电路
- 我们不应歧视任何语言,她们都是萌娘!(有图有真相)
- halcon多模板匹配,每种模板匹配结果不同颜色轮廓
- 怎么把做好的ps保存成图片_PS保存图片提示“无法完成请求”,这里有4种解决方法...
- 北京,探索「宜居」的技术路径
- 在 Lenovo G360 笔记本上安装 Debian Squeeze AMD64
热门文章
- 苹果官网上架Apple Watch Series 3官翻机:1869元起
- adduser useradd userdel /etc/password【原创】
- Springboot starter开发之traceId请求日志链路追踪
- double类型最大值_2020重新出发,JAVA入门,数据类型
- java输入某年某个季度_Java获取某年某季度的第一天出错
- 厦门one_厦门外代荣获ONE全球船舶操作中心颁发的Sapphire Award奖
- 【Kafka】Kafka 镜像 Kafka mirroring (MirrorMaker)
- 【Kafka】kafka 客户端 控制台 flink 都无法消费的情况
- 【kafka】Kafka 1.1.0 consumer group位移重设
- Arthas : 在线分析诊断工具Arthas(阿尔萨斯)