poj 2891 Strange Way to Express Integers——使用中国剩余定理中处理某些方程模数不互质的方法

是一边读入一边算的……先开始只要读到无解的情况就直接跳出来,一直wa,最后才知道原来还要把后面的数据读完才行,汗……

参考了AC大神的思路:

http://hi.baidu.com/aekdycoin/blog/item/71d7a842b93f611b73f05da4.html

这里稍微证明一下:
给定方程
x = c1 (mod b1) ……………………(1)
x = c2(mod b2) ………………………(2)
(b1,b2)可以不为1
于是通过取mod 定义,我们得到

x = k1 * b1 + c1………………(3)
(3) 带入(2)
k1 * b1 + c1 = c2 (mod b2)…………(4)
化简
k1 * b1 = c2 - c1 (mod b2)…………(5)
于是可以解得到
令G = gcd(b1,b2),C = c2 - c1 (mod b2)
那么由(5)得到
k1 * b1 = W * b2 + C
---->>>>>
k1 * b1 / G = W * b2 / G + C / G
令C'  = C/G
k1 * b1 / G = W * b2 / G + C '
k1 * b1 / G = C' (mod b2 / G)
--->
k1 = K (mod b2/G)………………(6)

那么有
k1 = k' * b2/G + K………………(7)
(7)带入(3)
x = k' * b2 * b1/G + K * b1 + c1………………(8)
x = K*b1 + c1 (mod b1 * b2/G)

a27400 2891 Accepted 404K 16MS G++ 1365B 2011-09-07 23:05:05
#include<cstdio>
#include
<cstdlib>
#include
<cstring>
#include
<cmath>
#include
<algorithm>

using namespace std;

typedef
struct
{
long long d;
long long x;
long long y;
}E;

E ee(
long long a,long long b)
{
if(b==0)
{
E k
={a,1,0};
return k;
}
E m
=ee(b,a%b);
E k
={m.d,m.y,m.x-(a/b)*(m.y)};
return k;
}

long long mod(long long a,long long b,long long n)//计算ax=b(mod n)
{
b
=(b+n)%n;
E m
=ee(a,n);
if(b%(m.d)) return -1;
long long e=(m.x)*(b/(m.d))%n+n;
return e%(n/(m.d));
}

long long gcd(long long a,long long b)
{
if(b==0)
return a;
else return gcd(b,a%b);
}


int main(void)
{
int k;
while(scanf("%d",&k)==1)
{
long long c1,b1;
scanf(
"%lld %lld",&b1,&c1);
if(k==1)
{
if(b1<=c1)
puts(
"-1");
else
printf(
"%lld\n",c1);
continue;
}
int i;
int flag=0;
for(i=2;i<=k;i++)
{
long long c2,b2;
scanf(
"%lld %lld",&b2,&c2);
if(flag)
continue;
if(b2<=c2)
{
flag
=1;
continue;
}
long long temp=gcd(b1,b2);
if((long long)fabs(c2-c1)%temp)
{
flag
=1;
continue;
}
long long y=mod(b1/temp,(c2-c1)/temp,b2/temp);
if(y==-1)
{
flag
=1;
continue;
}
c1
=(y*b1+c1)%(b1/temp*b2);
b1
=b1/temp*b2;
}
if(flag==1)
puts(
"-1");
else printf("%lld\n",c1%b1);
}
}

  

你可能感兴趣的:(Integer)