题意: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 }

【poj 2891】Strange Way to Express Integers(数论--拓展欧几里德 求解同余方程组 模版题)的更多相关文章

  1. POJ 2891 Strange Way to Express Integers(拓展欧几里得)

    Description Elina is reading a book written by Rujia Liu, which introduces a strange way to express ...

  2. POJ 2891 Strange Way to Express Integers【扩展欧几里德】【模线性方程组】

    求解方程组 X%m1=r1 X%m2=r2 .... X%mn=rn 首先看下两个式子的情况 X%m1=r1 X%m2=r2 联立可得 m1*x+m2*y=r2-r1 用ex_gcd求得一个特解x' ...

  3. 【poj 1061】青蛙的约会(数论--拓展欧几里德 求解同余方程)

    题意:已知2只青蛙的起始位置 a,b 和跳跃一次的距离 m,n,现在它们沿着一条长度为 l 的纬线(圈)向相同方向跳跃.问它们何时能相遇?(好有聊的青蛙 (΄◞ิ౪◟ิ‵) *)永不相遇就输出&quo ...

  4. 【hdu 3579】Hello Kiki(数论--拓展欧几里德 求解同余方程组)

    题意:Kiki 有 X 个硬币,已知 N 组这样的信息:X%x=Ai , X/x=Mi (x未知).问满足这些条件的最小的硬币数,也就是最小的正整数 X. 解法:转化一下题意就是 拓展欧几里德求解同余 ...

  5. 【hdu 1573】X问题(数论--拓展欧几里德 求解同余方程组的个数)

    题目:求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], -, X mod a[i] = b[i] ...

  6. poj 2891 Strange Way to Express Integers (非互质的中国剩余定理)

    Strange Way to Express Integers Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 9472   ...

  7. poj——2891 Strange Way to Express Integers

    Strange Way to Express Integers Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 16839 ...

  8. [POJ 2891] Strange Way to Express Integers

    Strange Way to Express Integers Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 10907 ...

  9. POJ 2891 Strange Way to Express Integers 中国剩余定理 数论 exgcd

    http://poj.org/problem?id=2891 题意就是孙子算经里那个定理的基础描述不过换了数字和约束条件的个数…… https://blog.csdn.net/HownoneHe/ar ...

随机推荐

  1. 详解线程池的作用及Java中如何使用线程池

    服务端应用程序(如数据库和 Web 服务器)需要处理来自客户端的高并发.耗时较短的请求任务,所以频繁的创建处理这些请求的所需要的线程就是一个非常消耗资源的操作.常规的方法是针对一个新的请求创建一个新线 ...

  2. 【剑指 Offer】10-I.斐波那契数列

    题目描述 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项.斐波那契数列的定义如下: F(0) = 0,   F(1) = 1 F(N) = F(N - 1) + F(N - ...

  3. Manjaro Linux 5.9.11-3安装和配置全局截图工具FlameShot教程

    背景说明 截图工具是日常适用频率较高的一种系统工具,在Linux下也有不少常用截图工具,如deepin-screenshot等,但是今天我们要介绍的是FlameShot--一款更加精致的Linux全局 ...

  4. Linux学习笔记 | 配置ssh

    目录: SSH的必要性 将默认镜像源修改为清华镜像源 Linux安装ssh软件 使用putty软件实现ssh连接 Windows下安装winscp SSH的必要性 一般服务器都位于远程而非本地,或者及 ...

  5. MySQL 使用MD5对数据进行加密

    数据库MD5加密 -- ================ 测试 MD5 加密 ============== CREATE TABLE `testmd5`( id INT(11) NOT NULL AU ...

  6. mysql: Character set 'utf8mb4' is not a compiled character set and is not specified in the '/usr/share/mysql/charsets/Index.xml' file

    mysql: Character set 'utf8mb4' is not a compiled character set and is not specified in the '/usr/sha ...

  7. 【Oracle】迁移表到其他的表空间

    有些时候需要将表迁移到其他的表空间,在将表空间做相关的操作 下面是命令如何迁移表空间 SQL> alter table 表名 move tablespace 表空间名; 如果有很多的表想要迁移的 ...

  8. Java反射全解析(使用、原理、问题、在Android中的应用)

    前言 今天说Java模块内容:反射. 反射介绍 正常情况下,我们知晓我们要操作的类和对象是什么,可以直接操作这些对象中的变量和方法,比如一个User类: User user=new User(); u ...

  9. Android之Xposed

    基础书籍推荐:1.疯狂JAVA讲义:2.疯狂安卓讲义: 逆向分析必须知道他的原理,不然只会用工具,那就直接GG. 谷歌的镜像网站:https://developers.google.com/andro ...

  10. DC-DC变换器,24v转5v稳压芯片,3A输出电流

    在24V输入中,比较合适的LDO可以选择:PW6206,输出电压3V,3.3V,5V 输入电压最高40V,功耗也低4uA左右,采用SOT23-3封装. PW6206系列是一个高精度,高输入电压低静态电 ...