http://poj.org/problem?id=2891

7
11323 9793
5537 4754
21538 10901
16118 203
2082 1209
22929 9510
16541 15898


4
18373 16147
8614 14948
8440 17480
22751 21618
6
19576 8109
18992 24177
9667 17726
16743 19533
16358 12524
8280 22731
4
9397 38490
22001 25094
33771 38852
19405 35943

ans

32439
13052907343337200
-1
78383942913636233

题目mod的数字并不互质,那怎么办呢?

记mod[i]表示第i个mod的数字,r[i]表示余数,那么观察前两项

总有X = k1 * mod[1] + r[1];

X = k2 * mod[2] + r[2];

那么k1 * mod[1] - k2 * mod[2] = r[2] - r[1]

这是可以用扩展欧几里德算法求得最小的解k1 (k1可以等于0,不一定要>0,我就是规定满足k1>0后不断溢出,所以wa)

那么得到满足前两个数字的解是(就是满足%mod[1] = r[1] , %mod[2] = r[2])的解。ansx = k1 * mod[1] + r[1]

然后往下合并

怎么往下合并呢?

就是把前面两条等式,变成了 % lcm(mod[1], mod[2]) = rr了,这个rr可以自己解出来,ansx % lcm(mod[1], mod[2])就是了

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string> const int maxn = + ;
LL mod[maxn];
LL r[maxn];
LL gcd(LL n, LL m) {
if (n % m == ) return m;
else return gcd(m, n % m);
}
LL lcm(LL n, LL m) {
return n / gcd(n, m) * m;
}
LL exgcd (LL a,LL mod,LL &x,LL &y) {
//求解a关于mod的逆元 ★:当且仅当a和mod互质才有用
if (mod==) {
x=;
y=;
return a;//保留基本功能,返回最大公约数
}
LL g=exgcd(mod,a%mod,x,y);
LL t=x; //这里根据mod==0 return回来后,
x=y; //x,y是最新的值x2,y2,改变一下,这样赋值就是为了x1=y2
y=t-(a/mod)*y; // y1=x2(变成了t)-[a/mod]y2;
return g; //保留基本功能,返回最大公约数
}
bool get_min_number (LL a,LL b,LL c,LL &x,LL &y) { //得到a*x+b*y=c的最小整数解
LL abGCD = gcd(a,b);
if (c % abGCD != ) return ;//不能整除GCD的话,此方程无解
a /= abGCD;
b /= abGCD;
c /= abGCD;
LL tx,ty;
exgcd(a,b,tx,ty); //先得到a*x+b*y=1的解,注意这个时候gcd(a,b)=1
x = tx * c;
y = ty * c; //同时乘上c,c是约简了的。得到了一组a*x + b*y = c的解。
LL haveSignB = b;
if (b < ) b = -b; //避免mod负数啊
x = (x % b + b) % b; //最小解
// if (x == 0) x = b; //避免x = 0不是"正"整数 不要用这个,溢出
y = (c - a * x) / haveSignB;
return ;//1代表可以
}
int n;
void work () {
for (int i = ; i <= n; ++i) {
scanf("%lld%lld", &mod[i], &r[i]);
}
LL mm = mod[];
LL rr = r[];
LL ansx = ;
for (int i = ; i <= n; ++i) {
LL x, y;
int ret = get_min_number(mm, -mod[i], r[i] - rr, x, y);
if (ret == ) {
printf("-1\n");
return;
}
ansx = x * mm + rr;
mm = lcm(mm, mod[i]);
rr = ansx % mm;
}
printf("%lld\n", rr);
return;
} int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
while(scanf("%d", &n) != EOF && n) {
work();
}
return ;
}

为什么rr就是最小解呢?余数当然是最小的解啊。。。

POJ 2891 Strange Way to Express Integers 中国剩余定理MOD不互质数字方法的更多相关文章

  1. poj Strange Way to Express Integers 中国剩余定理

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

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

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

  3. poj——2891 Strange Way to Express Integers

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

  4. [POJ 2891] Strange Way to Express Integers

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

  5. poj 2891 Strange Way to Express Integers (扩展gcd)

    题目链接 题意:给k对数,每对ai, ri.求一个最小的m值,令m%ai = ri; 分析:由于ai并不是两两互质的, 所以不能用中国剩余定理. 只能两个两个的求. a1*x+r1=m=a2*y+r2 ...

  6. POJ.2891.Strange Way to Express Integers(扩展CRT)

    题目链接 扩展中国剩余定理:1(直观的).2(详细证明). [Upd:]https://www.luogu.org/problemnew/solution/P4774 #include <cst ...

  7. POJ 2891 Strange Way to Express Integers 中国剩余定理解法

    一种不断迭代,求新的求余方程的方法运用中国剩余定理. 总的来说,假设对方程操作.和这个定理的数学思想运用的不多的话.是非常困难的. 參照了这个博客的程序写的: http://scturtle.is-p ...

  8. poj 2891 模数不互质的中国剩余定理

    Strange Way to Express Integers Description Elina is reading a book written by Rujia Liu, which intr ...

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

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

随机推荐

  1. 用遗传算法解决TSP问题

    浅谈遗传算法:https://www.cnblogs.com/AKMer/p/9479890.html Description \(小m\)在踏上寻找\(小o\)的路程之后不小心碰到了大魔王\(fat ...

  2. cs2008中头文件交叉编译的问题

    使用全局变量 使用基类指针定义在头文件中,在实际使用中强制转型为需要的指针,当然应该也可以存为空指针.

  3. DSP/BIOS程序启动顺序

    基于TI的DSP芯片的应用程序分为两种:一般应用程序:DSP/BIOS应用程序. 为简化编程,TI提供了一套C的编程接口,它以API和宏的形式封装了TI的所有硬件模块,这套接口统称DSP/BIOS.D ...

  4. 使用cmd命令行方式登录ftp上传下载数据

    部分用户在使用ftp工具登录空间上传下载过程中经常会遇到各种问题,如主动模式,被动模式,以及其他导致无法登陆ftp .上传数据.下载数据的问题,这时候不妨使用一下命令行方式.命令行下可以避免很多由于f ...

  5. HDOJ5441(图论中的并查集)

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ; ; ; ...

  6. 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

    目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...

  7. CUDA V9.2 sample编译问题

    这个哥们也遇到一样的问题 CUDA 9.1/9.2 与 Visual Studio 2017 (VS2017 15.6.4) 的不兼容问题 错误有显示 #if _MSC_VER < 1600 | ...

  8. varnish安装和配置

    实验环境:CentOS7 Varnish是高性能开源的反向代理服务器和HTTP缓存服务器. #varnish服务器:172.16.252.142 [root@varnish localhost]#yu ...

  9. linux docket

    什么是 Docker Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于  ...

  10. sql语句去重 最后部分没看 看1 有用

    一 数据库 1.常问数据库查询.修改(SQL查询包含筛选查询.聚合查询和链接查询和优化问题,手写SQL语句,例如四个球队比赛,用SQL显示所有比赛组合:举例2:选择重复项,然后去掉重复项:) 数据库里 ...