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

解法:拓展欧几里德求解同余方程组的最小非负整数解。(感觉挺不容易的......+_+@)

先看前2个关系式:                       m%a1=r1 和 m%a2=r2 
                                                            m-a1*x=r1 和 m-a2*y=r2 →
                                                            m=a1*x+r1 和 m=a2*y+r2
                                                            a1*x-a2*y=r2-r1
       于是用拓展欧几里德求得一个满足这2个关系式/方程联立的最小非负整数解 (x',y')。
  那么存在一个:                                  m'-a1*x'=r1 和 m'-a2*y'=r2 
                                                            m'=a1*x'+r1=a2*y'+r2
                                                            m' %a1=m%a1 和 m' %a2=m%a2 
                                                            m' %lcm(a1,a2)=m%lcm(a1,a2)
                                                            m=m'+k*lcm(a1,a2)
                                                            m=(a1*x'+r1)+lcm(a1,a2)*k
                                                            m=      r'       +         a'    *x
                                                           
......
                                                           
m=ak*y'+rk+lcm(ak-1,ak)*k
                                                  而又   m=ak*y'+rk , r'=ak*y'+rk
                                                  所以   m=r'
       接着继续将这个式子与  m=a3*y+r3 联立,同样地得到一个新的方程,再一直继续联立下去,由于 x 保证了尽量下,最后的 r' 就是尽量小的答案。

 1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6 typedef long long LL;
7
8 LL mabs(LL x) {return x>0?x:-x;}
9 LL exgcd(LL a,LL b,LL& x,LL& y)
10 {
11 if (!b) {x=1,y=0; return a;}
12 LL d,tx,ty;
13 d=exgcd(b,a%b,tx,ty);
14 x=ty,y=tx-(a/b)*ty;
15 return d;
16 }
17 int main()
18 {
19 LL k;
20 while (scanf("%I64d",&k)!=EOF)
21 {
22 LL aa,rr,a,r; bool ok=false;
23 for (LL i=1;i<=k;i++)
24 {
25 scanf("%I64d%I64d",&aa,&rr);
26 if (ok) continue;
27 if (i==1) a=aa,r=rr;
28 else
29 {//求解同余方程
30 LL d,x,y,t;
31 d=exgcd(a,aa,x,y);//ax-aay=rr-r 有无正负号没有关系
32 if ((rr-r)%d!=0) {ok=true;continue;}//break;} 多组数据要读入完!
33 x=x*((rr-r)/d);//1个解
34 t=mabs(aa/d);//mabs
35 x=(x%t+t)%t;//最小非负整数解
36
37 r=a*x+r,a=a*aa/d;//a=lcm(a,aa)=a*aa/gcd(a,aa)=a*aa/d;
38 }
39 }
40 if (!ok) printf("%I64d\n",r);
41 else printf("-1\n");
42 }
43 return 0;
44 }

最新文章

  1. 跟着思维导图学习javascript
  2. 关于html自闭合标签要不要加空格和斜杠的问题?
  3. JQuery源码分析(二)
  4. bzoj 2049: [Sdoi2008]Cave 洞穴勘测 动态树
  5. Delphi 重启应用程序(创建Bat文件的Process)
  6. State模式学习笔记
  7. 常见的排序算法总结(JavaScript)
  8. RocketMQ-消费重试机制
  9. Springboot整合Mybatis-puls
  10. 日历插件bootstrap-datetimepicker的使用感悟
  11. Codeforces 982E Billiard exgcd
  12. [BOZJ2721]樱花
  13. 【前言】Go语言开坑
  14. Redis简明教程
  15. Gulp Error: Cannot find module &#39;jshint/src/cli&#39;
  16. win7 &quot;com surrogate“ 已停止工作的解决办法
  17. Java输入输出流详解(转)
  18. Swift3 倒计时按钮扩展
  19. Windows虚拟地址转物理地址(原理+源码实现,附简单小工具)
  20. python-利用Python窗口可视化抽象开发山寨版翻译软件

热门文章

  1. 路由器开启远程控制(ssh或telent)
  2. js 数组的方法总结
  3. 剑指offer 查找和排序的基本操作:查找排序算法大集合
  4. Hash Tables and Hash Functions
  5. 【EXPDP/IMPDP】ORACLE数据泵导入导出案例(expdp & impdp)
  6. 利用JavaUDPSocket+多线程模拟实现一个简单的聊天室程序
  7. 前端知识(二)05-Eslint语法规范检查-谷粒学院
  8. 解决Linux下mysql区分大小写的问题
  9. Netty之ChannelHandler
  10. 如何实现new,call,apply,bind的底层原理。