我作为一个初中蒟蒻,听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\)次后变为一个式子。最后剩下的式子就满足我们的答案。

注意:

  1. \(lcm(a_1, a_2)\)和\(\% \frac{a_2}{d}\),需要取绝对值。又因为\(d = gcd(a_1, -a_2)\),我们不知道\(a_1\)的正负性(可能是上一步推过来的)。

  2. \(\% \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相关推荐

  1. AcWing 204. 表达整数的奇怪方式

    这道题我第一眼居然想着用二分法做,结果,还是不满足二分条件. WA代码如下 #include<iostream>using namespace std;const int N=30;int ...

  2. 204. 表达整数的奇怪方式(exgcd,,,数学推导,借助中国剩余定理)

    204. 表达整数的奇怪方式 题意: y总的笔记 墨染空大佬的 题解%%%%% AC # include <bits/stdc++.h> using namespace std; type ...

  3. 数论练习1 ( 曹冲养猪 + [POJ 2891]Strange Way to Express Integers + 乘法逆元【带证明】)

    虽然作业还没有做完,但是我还是放不下它,对此,我只想说: 今天你对作业爱理不理,明天它就让你补到飞起 DP先放放,我们要雨露均沾 练习上手:乘法逆元 题目 题解 代码实现 曹冲养猪?(互质的中国剩余定 ...

  4. 【poj 2891】Strange Way to Express Integers(数论--拓展欧几里德 求解同余方程组 模版题)...

    题意:Elina看一本刘汝佳的书(O_O*),里面介绍了一种奇怪的方法表示一个非负整数 m .也就是有 k 对 ( ai , ri ) 可以这样表示--m%ai=ri.问 m 的最小值. 解法:拓展欧 ...

  5. [POJ2891] Strange Way to Express Integers

    题目描述 FJ正在读佳佳写的一本书,书中描述一种表示非负整数的方法:选择k个不同的正整数a1,a2,-,ak,对于某个整数m分别对ai求余对应整数ri,如果适当选择a1,a2,-,ak,那么整数m可由 ...

  6. 【poj2891】 Strange Way to Express Integers

    poj.org/problem?id=2891 (题目链接) 题意:求解线性同余方程组,不保证模数一定两两互质. Solotion 用exgcd将俩个同余方程合并成一个 如合并n%M=R,n%m=r ...

  7. 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, ...

  8. POJ2891 Strange Way to Express Integers【扩展中国剩余定理】

    题目大意 就是模板...没啥好说的 思路 因为模数不互质,所以直接中国剩余定理肯定是不对的 然后就考虑怎么合并两个同余方程 \(ans = a_1 + x_1 * m_1 = a_2 + x_2 * ...

  9. 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 ...

最新文章

  1. Go 知识点(01)— 主协程与子协程执行顺序
  2. 迁移学习与跨域推荐,以及解决跨域推荐的方法
  3. 前端工程化工具Fekit分析
  4. 【 FPGA 】特定情况下消除不稳定态的方法
  5. Win10下IIS配置图解、MVC项目发布图解、IIS添加网站图解
  6. 如何写出健壮的代码?
  7. 邮件系统之webmail
  8. 在VS Code中直接调试Web程序,是怎样一种体验?
  9. SpringBoot集成thymeleaf增删改查示例
  10. 优化算法笔记|飞蛾扑火优化算法理解及实现
  11. 15 张图, 把TCP/IP 讲得一清二楚!
  12. 高通最强芯片855发布!AI性能比华为苹果翻倍,商用5G,标配屏下指纹
  13. 天河二号计算机是微型计算机,计算机二级考试真题-PPT-天河二号超级计算机
  14. 通过这18000个Python项目对比,并从中精选出 45 个值得学习的!
  15. 继电器触点RC吸收电路
  16. 我们不应歧视任何语言,她们都是萌娘!(有图有真相)
  17. halcon多模板匹配,每种模板匹配结果不同颜色轮廓
  18. 怎么把做好的ps保存成图片_PS保存图片提示“无法完成请求”,这里有4种解决方法...
  19. 北京,探索「宜居」的技术路径
  20. 在 Lenovo G360 笔记本上安装 Debian Squeeze AMD64

热门文章

  1. 苹果官网上架Apple Watch Series 3官翻机:1869元起
  2. adduser useradd userdel /etc/password【原创】
  3. Springboot starter开发之traceId请求日志链路追踪
  4. double类型最大值_2020重新出发,JAVA入门,数据类型
  5. java输入某年某个季度_Java获取某年某季度的第一天出错
  6. 厦门one_厦门外代荣获ONE全球船舶操作中心颁发的Sapphire Award奖
  7. 【Kafka】Kafka 镜像 Kafka mirroring (MirrorMaker)
  8. 【Kafka】kafka 客户端 控制台 flink 都无法消费的情况
  9. 【kafka】Kafka 1.1.0 consumer group位移重设
  10. Arthas : 在线分析诊断工具Arthas(阿尔萨斯)