这玩意一直以为很难的
...
结果看了几十分钟后发现就是个很简单的东西
...
先看一个题目:
x=a1(mod m1)x=a2(mod m2)...x=an(mod mn)
给出
ai,mi
,求出所有的
x
。
设
M=∏mi(1≤i≤n)
,
Mi=M/mi
,
Ti(TiMi≡1(mod mi))
则有
x=kM+∑aiTiMi(1≤i≤n),k∈Z
。
证明:
令
x=∑aiTiMi(1≤i≤n)
。
则有
aiTiMi≡ai(mod mi),ajTjMj≡0(mod mi)(i≠j)
。
因此
x
是满足上述方程组的。
∀i,x2−x1≡0(mod mi)⇒(所有的mi互质) x2−x1≡0(mod M)
。
所以任意两解之间都相差
M
的整数倍,因此解的形式就是:
顺便扔道裸题上来,poj1006:
AC code:
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#define pb push_back
#define mp make_pair
typedef long long LL;
typedef double DB;
typedef long double LD;
using namespace std;
const int MODP = 23;
const int MODE = 28;
const int MODI = 33;
int pow_mod(int a, int b, int p)
{
int ret = 1, base = a;
while(b)
{
if(b&1) ret = ret*base%p;
base = base*base%p;
b >>= 1;
}
return ret;
}
int inv(int x, int p)
{
if(p == 23) return pow_mod(x, p-2, p);
else if(p == 28) return pow_mod(x, 11, p);
else return pow_mod(x, 19, p);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
int Test = 1;
int p, e, i, d, x;
int M, MP, ME, MI;
int tp, te, ti;
M = MODP*MODE*MODI;
MP = M/MODP, ME = M/MODE, MI = M/MODI;
tp = MP*inv(MP, MODP), te = ME*inv(ME, MODE), ti = MI*inv(MI, MODI);
while(true)
{
scanf("%d%d%d%d", &p, &e, &i, &d);
if(p == -1) break;
x = p*tp+e*te+i*ti;
if(x > d) x -= (x-d-1)/M*M;
else x += (d-x+M)/M*M;
x -= d;
printf("Case %d: the next triple peak occurs in %d days.\n", Test++, x);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}