您的位置:首页 > 其它

【POJ】【2891】Strange Way to Express Integers

2015-04-02 18:22 423 查看

中国剩余定理/扩展欧几里得

  题目大意:求一般模线性方程组的解(不满足模数两两互质)

  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

Source Code
Problem: 2891        User: sdfzyhy
Memory: 676K        Time: 0MS
Language: G++        Result: Accepted

Source Code

//POJ 2891
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
typedef long long LL;
inline LL getLL(){
LL r=1,v=0; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1;
for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0';
return r*v;
}
const int N=1e5+10,INF=~0u>>2;
/******************template*********************/
LL a
,r
,n;
void exgcd(LL a,LL b,LL &d,LL &x,LL &y){
if (!b){d=a;x=1;y=0;}
else{ exgcd(b,a%b,d,y,x);y-=(a/b)*x;}
}
LL ex_CRT(LL *m,LL *r,int n){
LL M=m[1],R=r[1],x,y,d;
F(i,2,n){
exgcd(M,m[i],d,x,y);
if ((r[i]-R)%d) return -1;
x = (r[i] - R) / d * x % (m[i] / d);
R += x * M;
M = M / d * m[i];
R %= M;
}
return R > 0 ? R :R + M;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("2891.in","r",stdin);
freopen("2891.out","w",stdout);
#endif
while(scanf("%lld",&n)!=EOF){
F(i,1,n) a[i]=getLL(),r[i]=getLL();
printf("%lld\n",ex_CRT(a,r,n));
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: