怎样求同余方程组?如:

\[\begin{cases}
x \equiv a_1 \pmod {m_1} \\
x \equiv a_2 \pmod {m_2} \\
\cdots \\
x \equiv a_n \pmod {m_n}
\end{cases}\]

不保证 \(m\) 两两互素?

两两合并!

比方说

\[\begin{cases}
x \equiv a_1 \pmod {m_1} \\
x \equiv a_2 \pmod {m_2} \\
\end{cases}\]

就是

\[\begin{cases}
x = m_1x_1+a_1\\
x = m_2x_2+a_2\\
\end{cases}\]

可以变形成

\[m_1x_1+m_2(-x_2)=a_2-a_1
\]

拿扩欧搞掉这个方程。我们肯定想让 \(x\) 最小,那就让 \(x_1\) 最小,这样就求出了 \(x\) 的特解 \(x'\)。

显然, \(x\) 的通解是 \(x=x'+[m_1,m_2] \times t ,t \in \mathbb{Z}\)。

这也就很像是

\[x \equiv x' \pmod {[m_1,m_2]}
\]

我们惊喜地发现两个方程变成了一个方程。一路做下去就好了。

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n;
ll a, r, m, aa, rr, x, y;
bool flag;
ll exgcd(ll a, ll b, ll &x, ll &y){
if(!b){
x = 1;
y = 0;
return a;
}
ll re=exgcd(b, a%b, x, y);
ll z=x;
x = y;
y = z - a / b * y;
return re;
}
int main(){
while(scanf("%d", &n)!=EOF){
flag = true;
n--;
scanf("%lld %lld", &aa, &rr);
while(n--){
scanf("%lld %lld", &a, &r);
if(!flag) continue;
ll gcd=exgcd(aa, a, x, y);
if((r-rr)%gcd) flag = false;
else
x = (((r-rr)/gcd*x)%(a/gcd)+a/gcd)%(a/gcd);
x = rr + x * aa;
rr = x;
aa = a/gcd*aa;
}
if(flag) printf("%lld\n", x);
else printf("-1\n");
}
return 0;
}

如果保证两两互素呢?那就中国剩余定理了。记 \(m =\prod_{i=1}^n m_i\),\(M_i=m/m_i\),\(t_i\) 是 \(M_i\) 在模 \(m_i\) 意义下的乘法逆元,则一个特解是 \(\sum_{i=1}^n a_iM_it_i\)。通解是 \(\sum_{i=1}^n a_iM_it_i + mk, k \in \mathbb{Z}\)。

证明:因为当 \(i \not =j\)时,\(m_j|M_i\),则 \(a_iM_it_i \equiv 0 \pmod {m_j}\),而 \(a_jM_jt_j \equiv a_j \pmod {m_j}\),证毕。

#include <iostream>
#include <cstdio>
using namespace std;
int a[15], cnt, mul, ans, x, y, dd;
const int m[]={0, 23, 28, 33};
int exgcd(int aa, int bb, int &x, int &y){
if(!bb){
x = 1;
y = 0;
return aa;
}
int re=exgcd(bb, aa%bb, x, y);
int z=x;
x = y;
y = z - aa / bb * y;
return re;
}
int ni(int aa, int bb){
int gcd=exgcd(aa, bb, x, y);
return (x%bb+bb)%bb;
}
int main(){
while(scanf("%d %d %d %d", &a[1], &a[2], &a[3], &dd)!=EOF){
mul = 1;
if(a[1]<0) break;
ans = 0;
for(int i=1; i<=3; i++)
a[i] %= m[i], mul *= m[i];
for(int i=1; i<=3; i++)
ans += a[i] * (mul/m[i])%mul * ni(mul/m[i], m[i])%mul;
ans -= dd;
ans = (ans%mul+mul)%mul;
if(!ans) ans += mul;
printf("Case %d: the next triple peak occurs in %d days.\n", ++cnt, ans);
}
return 0;
}

poj2891 Strange Way to Express Integers poj1006 Biorhythms 同余方程组的更多相关文章

  1. POJ 2891 Strange Way to Express Integers | exGcd解同余方程组

    题面就是让你解同余方程组(模数不互质) 题解: 先考虑一下两个方程 x=r1 mod(m1) x=r2 mod (m2) 去掉mod x=r1+m1y1   ......1 x=r2+m2y2   . ...

  2. 中国剩余定理+扩展中国剩余定理 讲解+例题(HDU1370 Biorhythms + POJ2891 Strange Way to Express Integers)

    0.引子 每一个讲中国剩余定理的人,都会从孙子的一道例题讲起 有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二.问物几何? 1.中国剩余定理 引子里的例题实际上是求一个最小的x满足 关键是,其中 ...

  3. POJ2891——Strange Way to Express Integers(模线性方程组)

    Strange Way to Express Integers DescriptionElina is reading a book written by Rujia Liu, which intro ...

  4. POJ2891 Strange Way to Express Integers

    题意 Language:Default Strange Way to Express Integers Time Limit: 1000MS Memory Limit: 131072K Total S ...

  5. POJ2891 Strange Way to Express Integers 扩展欧几里德 中国剩余定理

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ2891 题意概括 给出k个同余方程组:x mod ai = ri.求x的最小正值.如果不存在这样的x, ...

  6. P4777 【模板】扩展中国剩余定理(EXCRT)/ poj2891 Strange Way to Express Integers

    P4777 [模板]扩展中国剩余定理(EXCRT) excrt模板 我们知道,crt无法处理模数不两两互质的情况 然鹅excrt可以 设当前解到第 i 个方程 设$M=\prod_{j=1}^{i-1 ...

  7. POJ2891 - Strange Way to Express Integers(模线性方程组)

    题目大意 求最小整数x,满足x≡a[i](mod m[i])(没有保证所有m[i]两两互质) 题解 中国剩余定理显然不行....只能用方程组两两合并的方法求出最终的解,刘汝佳黑书P230有讲~~具体证 ...

  8. POJ2891 Strange Way to Express Integers [中国剩余定理]

    不互质情况的模板题 注意多组数据不要一发现不合法就退出 #include <iostream> #include <cstdio> #include <cstring&g ...

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

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

随机推荐

  1. python堆排序实现TOPK问题

    # 构建小顶堆跳转def sift(li, low, higt): tmp = li[low] i = low j = 2 * i + 1 while j <= higt: # 情况2:i已经是 ...

  2. bzoj2301 [HAOI2011]Problem b【莫比乌斯反演 分块】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2301 很好的一道题.首先把每个询问转化为4个子询问,最后的结果就是这四个子询问的记过加加减减 ...

  3. python收发邮件的方法

    def acptmail(): email = 'xxx@163.com' #input('Email:') password = 'xxx' #input('Password: ') pop3_se ...

  4. req.getParameter()无法获取参数(附前端json序列化)

    问题:前端用Ajax的post方式想servlet传递参数,servlet的getParameter()方法无法获取参数. 前端代码: $.ajax({ url: '/TestWeb/addBook' ...

  5. 145 Binary Tree Postorder Traversal 二叉树的后序遍历

    给定一棵二叉树,返回其节点值的后序遍历.例如:给定二叉树 [1,null,2,3],   1    \     2    /   3返回 [3,2,1].注意: 递归方法很简单,你可以使用迭代方法来解 ...

  6. 分区表,磁盘概念和parted的使用

    分区表,磁盘概念和parted的使用 登录陌生系统首先要做的事: 个人认为,首先得知道Linux版本的什么:cat /etc/issue df:查看磁盘的分区和数据的分配情况,类型(NFS,ext4. ...

  7. spark block读写流程分析

    之前分析了spark任务提交以及计算的流程,本文将分析在计算过程中数据的读写过程.我们知道:spark抽象出了RDD,在物理上RDD通常由多个Partition组成,一个partition对应一个bl ...

  8. Vue 2.0入门基础知识之全局API

    3.全局API 3-1. Vue.directive 自定义指令 Vue.directive用于自定义全局的指令 实例如下: <body> <div id="app&quo ...

  9. cluvfy comp命令用法

    1.获取集群验证工具cluvfy的帮助信息 grid@rac1:/home/grid>cluvfy -help USAGE: cluvfy [ -help ] cluvfy stage { -l ...

  10. (转)在编写Spring框架的配置文件时,标签无提示符的解决办法

    http://blog.csdn.net/yerenyuan_pku/article/details/52831618 问题描述 初学者在学习Spring框架的过程中,大概会碰到这样一个问题:在编写S ...