HihoCoder - 1303 数论六·模线性方程组
裸的一个模线性方程组,重在理解一下这个求的过程。
#include<cstdio> #include<cstdlib> #include<iostream> #include<string> #include<set> #include<algorithm> #include<vector> #include<queue> #include<list> #include<cmath> #include<cstring> #include<map> #include<stack> using namespace std; #define INF 0x3f3f3f3f #define maxn 1005 #define ull unsigned long long #define ll long long #define hashmod 99999839 #define mod 9997 int n; ll m[maxn],r[maxn]; ll gcd(ll a,ll b){ return (b==0)?a:gcd(b,a%b); } ll exgcd(ll a,ll b,ll& x,ll& y){ if(!b){x = 1,y = 0;return a;} ll g = exgcd(b,a%b,x,y); ll t = x; x = y; y = t - a/b * x; return g; } void solve(){ bool f = true; ll x,y,z; for(int i = 2;i <= n;++i){ ll g = gcd(m[i-1],m[i]); if((r[i]-r[i-1])%g!=0){ f = false; break; } z=(r[i]-r[i-1])/g; exgcd(m[i-1]/g,m[i]/g,x,y);//AX+BY=1的(X,Y) x *= z;//y *= z,AX + BY = C x = x + (abs(x) / (m[i]/g) + 1) * (m[i]/g);//将X扩展为非负数,X = x + B/(A,B) = (x + K*B/(A,B)) % (B/(A,B)) x = x % (m[i]/g);//防止溢出 z = x * m[i-1]+r[i-1];//得到两个方程式的特解 m[i] = m[i]/g*m[i-1];//得到lcm(A,B) r[i] = z % m[i]; } if(f) printf("%lld\n",r[n]); else printf("%lld\n",-1ll); } int main(){ freopen("a.in","r",stdin); freopen("b.out","w",stdout); while(~scanf("%d",&n)){ for(int i = 1;i <= n;++i){ scanf("%d%d",&m[i],&r[i]); } solve(); } return 0; }