poj1006

数论跪了三天。。

这个题不难得到(n+d)%23=p;   (n+d)%28=e;   (n+d)%33=i 

如何求解?

首先介绍一个所谓“逆”的概念。

给定整数a,有(a,m)=1,称ax=1(mod m)的一个解叫做a模m的逆。

下面给出求逆的程序。

#include <iostream>
#include <math.h>

using namespace std;

typedef long long LL;

void gcd(LL a, LL b, LL &d, LL &x, LL &y)
{
    if(!b)
    {
        d = a, x = 1, y = 0;
    }
    else
    {
        gcd(b, a %b, d, y, x);
        y -= x * (a/b);
    }
}
LL inv(LL a, LL n)
{
    LL d, x, y;
    gcd(a,n,d,x,y);
    return d == 1 ? (x + n) % n : -1;
}
int main()
{
    LL a, m;
    while(cin>> a>>m)
    {
        cout << inv(a, m) <<endl;
    }
}

比如9模31的逆是7。可输入9 31,得出7。

“中国剩余定理”

http://en.wikipedia.org/wiki/Chinese_remainder_theorem

百度百科介绍的就是一坨屎,看都别看!

言归正传,如何解这个方程:

(n+d)%23=p;(n+d)%28=e;(n+d)%33=i;


大家看到了,都是让它的余数变成1(为了求逆)。“大衍求一术”。

----------------------------------------------------------------------

Finding the solution with basic algebra and modular arithmetic

For example, consider the problem of finding an integer x such that

\begin{align}  x &\equiv 2 \pmod{3} \\  x &\equiv 3 \pmod{4} \\  x &\equiv 1 \pmod{5}\end{align}

A brute-force approach converts these congruences into sets and writes the elements out to the product of 3×4×5 = 60 (the solutions modulo 60 for each congruence):

x ∈ {2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50, 53, 56, 59, …}
x ∈ {3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, …}
x ∈ {1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, …}

To find an x that satisfies all three congruences, intersect the three sets to get:

x ∈ {11, …}

Which can be expressed as

x \equiv 11 \pmod{60}

Another way to find a solution is with basic algebra, modular arithmetic, and stepwise substitution.

We start by translating these congruences into equations for some t, s, and u:

  • Equation 1: x = 2 + 3t
  • Equation 2: x = 3 + 4s
  • Equation 3: x = 1 + 5u

Start by substituting the x from equation 1 into congruence 2:

\begin{align}  2 + 3t &\equiv 3 \pmod{4} \\      3t &\equiv 1 \pmod{4} \\       t &\equiv (3)^{-1} \equiv 3 \pmod{4}\end{align}

meaning that t = 3 + 4s for some integer s.

Plug t into equation 1:

x = 2 + 3t = 2 + 3(3 + 4s) = 11 + 12s

Plug this x into congruence 3:

11 + 12s \equiv 1 \pmod{5}

Casting out fives, we get

 \begin{align}  1 + 2s &\equiv 1 \pmod{5} \\      2s &\equiv 0 \pmod{5}\end{align}

meaning that

s = 0 + 5u

for some integer u.

Finally,

x = 11 + 12s = 11 + 12(5u) = 11 + 60u

So, we have solutions 11, 71, 131, 191, …

Notice that 60 = lcm(3,4,5). If the moduli are pairwise coprime (as they are in this example), the solutions will be congruent modulo their product.

A constructive algorithm to find the solution

The following algorithm only applies if the \scriptstyle n_i's are pairwise coprime. (For simultaneous congruences when the moduli are not pairwise coprime, themethod of successive substitution can often yield solutions.)

Suppose, as above, that a solution is required for the system of congruences:

x \equiv a_i \pmod{n_i} \quad\mathrm{for}\; i = 1, \ldots, k

Again, to begin, the product \scriptstyle N \;=\; n_1n_2 \ldots n_k is defined. Then a solution x can be found as follows.

For each i the integers \scriptstyle n_i and \scriptstyle N/n_i are coprime. Using the extended Euclidean algorithm we can find integers \scriptstyle r_i and \scriptstyle s_i such that \scriptstyle r_in_i \,+\, s_iN/n_i \;=\; 1. Then, choosing the label \scriptstyle e_i \;=\; s_iN/n_i, the above expression becomes:

r_i n_i + e_i = 1

Consider \scriptstyle e_i. The above equation guarantees that its remainder, when divided by \scriptstyle n_i, must be 1. On the other hand, since it is formed as \scriptstyle s_iN/n_i, the presence of N guarantees a remainder of zero when divided by any \scriptstyle n_j when \scriptstyle j \;\ne\; i.

e_i \equiv 1 \pmod{n_i} \quad \mathrm{and} \quad e_i \equiv 0 \pmod{n_j} \quad \mathrm{for} ~ j \ne i

Because of this, and the multiplication rules allowed in congruences, one solution to the system of simultaneous congruences is:

x = \sum_{i=1}^k a_i e_i

For example, consider the problem of finding an integer x such that

\begin{align}  x &\equiv 2 \pmod{3} \\  x &\equiv 3 \pmod{4} \\  x &\equiv 1 \pmod{5}\end{align}

Using the extended Euclidean algorithm, for x modulo 3 and 20 [4×5], we find (−13) × 3 + 2 × 20 = 1; i.e., e1 = 40. For x modulo 4 and 15 [3×5], we get (−11) × 4 + 3 × 15 = 1, i.e. e2 = 45. Finally, for x modulo 5 and 12 [3×4], we get 5 × 5 + (−2) × 12 = 1, i.e. e3 = −24. A solution x is therefore 2 × 40 + 3 × 45 + 1 × (−24) = 191. All other solutions are congruent to 191 modulo 60, [3 × 4 × 5 = 60], which means they are all congruent to 11 modulo 60.

Note: There are multiple implementations of the extended Euclidean algorithm which will yield different sets of \scriptstyle e_1 \;=\; -20\scriptstyle e_2 \;=\; -15, and \scriptstyle e_3 \;=\; -24. These sets however will produce the same solution; i.e., (−20)2 + (−15)3 + (−24)1 = −109 = 11 modulo 60.

----------------------------------------------------------------------

那么,程序很简单

注意一点,如果直接对21252取余,再减去d,可能会出现负数的情况。

#include<iostream>

using namespace std;

int main()
{
	int p, e, i, d;
	int time = 1;
	while (cin >> p >> e >> i >> d)
	{
		if (p == -1 && e == -1 && i == -1 && d == -1)
			break;
		int n = (5544 * p + 14421 * e + 1288 * i - d + 21252) % 21252;
		if (n == 0)
			n = 21252;
		cout << "Case " << time++ << ": the next triple peak occurs in " << n << " days." << endl;
	}
}

请试着解下列同余方程组作为练习




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值