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. 简单易懂dubbo入门实例

    一.创建Maven多模块项目 项目结构如下 模块介绍: dubbo-api            ----API接口 dubbo-consumer ----消费者 dubbo-provider     ...

  2. C++STL 库中set容器应用

    #include<iostream> #include<cstdio> #include<set> using namespace std; set<int& ...

  3. Nuget:目录

    ylbtech-Nuget:目录 1.返回顶部 1. https://www.nuget.org 2. https://docs.microsoft.com/zh-cn/nuget/ 3. https ...

  4. VisualGDB系列3:安装VisualGDB

    根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 1 系统需求 系统需求如下: Micro ...

  5. 自定义echart tooltip格式

    formatter: function (tipData) { return tipData[0].name + '</br>' + '<span style="displ ...

  6. 解决启动SQL Server Management Studio 17时报Cannot find one of more components...的问题

    刚装好SSMS 17.1准备体验,弹出: 一番搜索,普遍办法都是安装VS2015独立shell.删除某个注册表项什么的,没用,首先这个shell我是装了的,然后也没有那个注册表项.我自己尝试过重装sh ...

  7. Structuring Machine Learning Projects 笔记

    1 Machine Learning strategy 1.1 为什么有机器学习调节策略 当你的机器学习系统的性能不佳时,你会想到许多改进的方法.但是选择错误的方向进行改进,会使你花费大量的时间,但是 ...

  8. C++中的对象的赋值和复制

    对象的赋值 如果对一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值,或者说,一个对象的值可以赋给另一个同类的对象.这里所指的对象的值是指对象中所有数据成员的值. 对象之间的赋值也是通过赋值 ...

  9. URL中#符号的作用

    转自http://blog.sina.com.cn/s/blog_6f9eb2dd0100sk97.html 一.#的涵义 #代表网页中的一个位置.其右面的字符,就是该位置的标识符.比如,       ...

  10. servlet与filter的加载顺序详解

     项目:3个filter,3个servlet,匹配的url路径/hello. 情况1:servlet没加<load-on-startup></load-on-startup>情 ...