概述
>Link
luogu P1495
>Description
求解一元线性同余方程组
{
x
≡
b
1
(
m
o
d
a
1
)
.
.
.
.
.
.
x
≡
b
n
(
m
o
d
a
n
)
left{begin{matrix}xequiv b_1(mod a_1) \ ...... \ xequiv b_n(mod a_n) end{matrix}right.
⎩⎨⎧x≡b1(moda1)......x≡bn(modan)
保证
a
a
a两两互质
>解题思路
#关于这道题
……因为用了unsigned long long调用太多内存爆了,所以只有60分,检查了好久(甚至还去对标 了)才检查出来要用longlong……
(笔记参考Bat特白)
#关于中国剩余定理
孙子定理是中国古代求解一次同余式组(见同余)的方法。是数论中一个重要定理。又称中国余数定理。
一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。 ——百度百科
求解一元线性同余方程组 { x ≡ 2 ( m o d 3 ) x ≡ 3 ( m o d 5 ) x ≡ 2 ( m o d 7 ) left{begin{matrix}xequiv 2(mod 3) \ xequiv 3(mod5) \ xequiv 2(mod7) end{matrix}right. ⎩⎨⎧x≡2(mod3)x≡3(mod5)x≡2(mod7)
将问题进行分解,使得(以下
m
o
d
mod
mod省略)
{
x
1
≡
2
(
3
)
,
x
1
≡
0
(
5
)
,
x
1
≡
0
(
7
)
x
2
≡
0
(
2
)
,
x
2
≡
3
(
5
)
,
x
2
≡
0
(
7
)
x
3
≡
0
(
2
)
,
x
3
≡
0
(
5
)
,
x
3
≡
2
(
7
)
left{begin{matrix}x_1equiv 2(3),x_1equiv 0( 5),x_1equiv 0( 7) \ x_2equiv 0(2),x_2equiv 3(5),x_2equiv 0(7) \x_3equiv 0(2),x_3equiv 0(5), x_3equiv 2(7) end{matrix}right.
⎩⎨⎧x1≡2(3),x1≡0(5),x1≡0(7)x2≡0(2),x2≡3(5),x2≡0(7)x3≡0(2),x3≡0(5),x3≡2(7)
此时
x
=
x
1
+
x
2
+
x
3
x=x_1+x_2+x_3
x=x1+x2+x3,
x
x
x的性质依然满足
再将问题进行分解,看
x
1
x_1
x1如何求
求
y
1
≡
1
(
3
)
,
y
1
≡
0
(
5
)
,
y
1
≡
0
(
7
)
y_1equiv 1(3),y_1equiv 0( 5),y_1equiv 0( 7)
y1≡1(3),y1≡0(5),y1≡0(7)
那么
x
1
=
2
∗
y
1
x_1=2*y_1
x1=2∗y1
这样求出所有的
y
y
y,
x
=
2
∗
y
1
+
3
∗
y
2
+
2
∗
y
3
x=2*y_1+3*y_2+2*y_3
x=2∗y1+3∗y2+2∗y3
但是此时
x
x
x还不是最小解,
x
x
x要不断减去
3
,
5
,
7
3,5,7
3,5,7的最小公倍数直到不能减(呃好吧其实就是直接取模
那么如何求
y
y
y??
因为
y
1
≡
1
(
3
)
,
y
1
≡
0
(
5
)
,
y
1
≡
0
(
7
)
y_1equiv 1(3),y_1equiv 0( 5),y_1equiv 0( 7)
y1≡1(3),y1≡0(5),y1≡0(7),所以
y
1
y_1
y1一定是
5
5
5和
7
7
7的公倍数,我们设
y
1
=
35
t
y_1=35t
y1=35t
那么现在就变成了
35
t
≡
1
(
3
)
35tequiv 1(3)
35t≡1(3),可以转化成
35
t
−
1
=
3
k
35t-1=3k
35t−1=3k
再转化一下:
35
t
−
3
k
=
1
35t-3k=1
35t−3k=1,这不就是exgcd吗!直接开始扩欧
(因为题目保证
a
i
a_i
ai与
a
j
a_j
aj互质,所以我们可以扩欧)
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
#define N 100000
using namespace std;
int n;
LL a[N], b[N], M, ans, m;
void ex_gcd (LL aa, LL bb, LL &x, LL &y)
{
if (!bb) {x = 1, y = 0; return;}
LL X = x, Y = y;
ex_gcd (bb, aa % bb, X, Y);
x = Y;
y = X - (aa / bb) * Y;
}
int main()
{
scanf ("%d", &n);
M = 1;
for (int i = 1; i <= n; i++)
{
scanf ("%lld%lld", &a[i], &b[i]);
M *= a[i];
}
for (int i = 1; i <= n; i++)
{
m = M / a[i];
LL x = 0, y = 0;
ex_gcd (a[i], m, x, y);
if (y <= 0) y += a[i];
ans += m * y * b[i];
}
printf ("%lld", ans % M);
return 0;
}
最后
以上就是优美咖啡为你收集整理的中国剩余定理(CRT)/曹冲养猪【模板】的全部内容,希望文章能够帮你解决中国剩余定理(CRT)/曹冲养猪【模板】所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复