Strange Way to Express Integers POJ 2891(中国剩余定理扩展)
Posted vbel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Strange Way to Express Integers POJ 2891(中国剩余定理扩展)相关的知识,希望对你有一定的参考价值。
原题
题目分析
题意很明确,这里的模数是不互质的,因此不能直接套中国剩余定理.这里稍微讲一下中国剩余定理的扩展,假设前i个方程的特解为ans(i),通解为x(i)=ans(i)+k*lcm(前i个模数).把x(i)代入到第i+1个方程,用扩展欧几里得定理求解k=k0,ans(i+1)=ans(i)+k0*lcm(前i个模数),则x(i+1)=ans(i+1)+lcm(前i+1个模数).大概思路就是这样,但有些细节需要注意一下,求出来的k0,ans(i+1)需要用求模的方法缩小一下.
代码
1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #include <algorithm> 5 #include <utility> 6 #include <ctime> 7 #include <cmath> 8 #include <cstring> 9 #include <string> 10 #include <stack> 11 #include <queue> 12 #include <vector> 13 #include <set> 14 #include <map> 15 16 using namespace std; 17 typedef unsigned long long ULL; 18 typedef __int64 LL; 19 typedef long double LB; 20 const int INF_INT=0x3f3f3f3f; 21 const LL INF_LL=0x3f3f3f3f3f3f3f3f; 22 23 vector<LL> a,m; 24 25 LL exgcd(LL a,LL b,LL &x,LL &y) 26 27 if(!b) 28 29 x=1,y=0; 30 return a; 31 32 LL g=exgcd(b,a%b,y,x); //简化写法 33 y-=a/b*x; //y从下一个方程回溯回来时是下一个方程的x 34 return g; 35 36 37 LL solve(LL n) 38 39 LL ans=0,lcm=1,x,y; 40 for(int i=0;i<n;i++) 41 42 if(!i) ans=a[i],lcm*=m[i]; 43 else 44 45 LL g=exgcd(lcm,m[i],x,y),c=a[i]-ans; 46 if(c%g) 47 48 ans=-1; 49 break; 50 51 x*=c/g; 52 LL t=m[i]/g; 53 x=(x%t+t)%t; 54 ans+=x*lcm; 55 lcm*=m[i]/g; 56 ans=((ans%lcm)+lcm)%lcm; 57 58 59 return ans; 60 61 62 int main() 63 64 // freopen("std.in","r",stdin); 65 // freopen("std.out","w",stdout); 66 LL k; 67 while(~scanf("%lld",&k)) 68 69 m.clear(),a.clear(); 70 LL x,y; 71 for(int i=0;i<k;i++) scanf("%lld %lld",&x,&y),m.push_back(x),a.push_back(y); 72 printf("%lld\n",solve(k)); 73 74 return 0; 75
以上是关于Strange Way to Express Integers POJ 2891(中国剩余定理扩展)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj Strange Way to Express Integersexcrt
POJ——T 2891 Strange Way to Express Integers
poj 2891 Strange Way to Express Integers 2012-09-05
POJ2891 Strange Way to Express Integers线性同余方程