【POJ】【2891】Strange Way to Express Integers
中国剩余定理/扩展欧几里得
题目大意:求一般模线性方程组的解(不满足模数两两互质)
solution:对于两个方程 \[ \begin{cases} m \equiv r_1 \pmod {a_1} \\ m \equiv r_2 \pmod{a_2} \end{cases} \] 我们可以列出式子 $$ a_1x+r_1=a_2y+r_2 $$ 利用扩展欧几里得解出一个可行解$M'$。那么我们就可以将两个限制条件合为一个: $$ m \equiv M' \pmod{ lcm(a_1,a_2)} $$ 这样我们依次合并下去即可得到答案啦~(话说代码里那段处理的过程我还没看懂……
代码:(copy自http://www.cnblogs.com/Missa/archive/2013/06/01/3112536.html)
1 Source Code 2 Problem: 2891 User: sdfzyhy 3 Memory: 676K Time: 0MS 4 Language: G++ Result: Accepted 5 6 Source Code 7 8 //POJ 2891 9 #include<vector> 10 #include<cstdio> 11 #include<cstring> 12 #include<cstdlib> 13 #include<iostream> 14 #include<algorithm> 15 #define rep(i,n) for(int i=0;i<n;++i) 16 #define F(i,j,n) for(int i=j;i<=n;++i) 17 #define D(i,j,n) for(int i=j;i>=n;--i) 18 using namespace std; 19 typedef long long LL; 20 inline LL getLL(){ 21 LL r=1,v=0; char ch=getchar(); 22 for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1; 23 for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0'; 24 return r*v; 25 } 26 const int N=1e5+10,INF=~0u>>2; 27 /******************template*********************/ 28 LL a[N],r[N],n; 29 void exgcd(LL a,LL b,LL &d,LL &x,LL &y){ 30 if (!b){d=a;x=1;y=0;} 31 else{ exgcd(b,a%b,d,y,x);y-=(a/b)*x;} 32 } 33 LL ex_CRT(LL *m,LL *r,int n){ 34 LL M=m[1],R=r[1],x,y,d; 35 F(i,2,n){ 36 exgcd(M,m[i],d,x,y); 37 if ((r[i]-R)%d) return -1; 38 x = (r[i] - R) / d * x % (m[i] / d); 39 R += x * M; 40 M = M / d * m[i]; 41 R %= M; 42 } 43 return R > 0 ? R :R + M; 44 } 45 int main(){ 46 #ifndef ONLINE_JUDGE 47 freopen("2891.in","r",stdin); 48 freopen("2891.out","w",stdout); 49 #endif 50 while(scanf("%lld",&n)!=EOF){ 51 F(i,1,n) a[i]=getLL(),r[i]=getLL(); 52 printf("%lld\n",ex_CRT(a,r,n)); 53 } 54 return 0; 55 }