题目链接
https://www.luogu.org/problemnew/show/P4777
分析
扩展CRT就是解决模数不互质的情况,说是扩展CRT,其实都是扩欧…
先来考虑两个方程的情况:x≡amodb和x≡cmodd
由方程1得x=tb+a,代入方程2中得tb+a≡cmodd,
把它变得更像方程:t×b+t′×d=c−a
解得t′后回代即可
那么对于多个方程组,假设对于前k个方程组我们已经求出一个解x,记M=∏ki=1mi,那么显然x+i×M是前k个方程的一个通解,因为M≡0modmi(i<=k)
那么我们要求的就是一个整数t,使得x+t×M≡bk+1modmk+1
移项得t×M+t′×mk+1=bk+1−x(这里的x其实是已知的)
运用扩欧算出t,更新x=x+t×M,然后M=M×mk+1
当然无解的情况也就是扩欧无解的情况,当bk+1−x不整除gcd(M,mk+1)时无解
注意
题目要求要将x化为最小整数解
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <cstdio> #include <algorithm> #include <cctype> #include <cstdlib> #include <cstring> #include <cmath> #include <iostream> #define ll __int128 #define ri register int using std::min; using std::max; template <class T>inline void read(T &x){ x=0;int ne=0;char c; while(!isdigit(c=getchar()))ne=c=='-'; x=c-48; while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48; x=ne?-x:x;return ; } const int maxn=100005; const int inf=0x7fffffff; ll b[maxn],m[maxn]; int n; ll exgcd(ll a,ll b,ll &x,ll &y){ if(b==0){x=1,y=0;return a;} ll d=exgcd(b,a%b,x,y); ll z=x;x=y,y=z-a/b*y; return d; } void print(ll x){ if(!x) return; if(x) print(x/10); putchar(x%10+'0'); } ll ans=0; int main(){ ll x,y,M,aa,bb,cc,d; bool flag=0; read(n); for(ri i=1;i<=n;i++){ read(m[i]),read(b[i]); } M=m[1],ans=b[1]; for(ri i=2;i<=n;i++){ aa=M,bb=m[i],cc=(b[i]-ans%bb+bb)%bb; x=0,y=0; d=exgcd(aa,bb,x,y); bb=bb/d; if(cc%d){flag=1;break;} x=((x*cc/d)%bb+bb)%bb; ans+=M*x;M*=bb; ans=(ans%M+M)%M; } if(flag)puts("-1"); else { if(!ans)puts("0"); else {print(ans);puts("");} } return 0; }
|
去评论