數論(擴充套件歐幾里得求方程整數解)
阿新 • • 發佈:2019-02-20
A - Solutions to an Equation
You have to find the number of solutions of the following equation:
Ax + By + C = 0
Where A, B, C, x, y are integers and x1 ≤ x ≤ x2 and y1 ≤ y ≤ y2.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case starts with a line containing seven integers A, B, C, x1, x2, y1, y2
Output
For each case, print the case number and the total number of solutions.
Sample Input
5
1 1 -5 -5 10 2 4
-10 -8 80 -100 100 -90 90
2 3 -4 1 7 0 8
-2 -3 6 -2 5 -10 5
1 8 -32 0 0 1 10
Sample Output
Case 1: 3
Case 2: 37
Case 3: 1
Case 4: 2
Case 5: 1
分析:
顯然用擴充套件歐幾里得求整數解,先貼一下大佬求解過程:
擴充套件歐幾里德演算法證明過程:
如何求其他解;
還要注意用不等式求解時,要討論正負號,為負數時不等式方向會改變,同小取小,同大取大
同時還要注意a==0&&b==0,a==0&&b!=0,a!=0&&b==0這三種情況要單獨討論
AC code:
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; 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-=x*(a/b); } } int main() { int t; cin>>t; ll a,b,c,x1,y1,x2,y2; int cas=0; while(t--) { ll x,y,gcd; cin>>a>>b>>c>>x1>>x2>>y1>>y2; c=-c;//變為擴充套件歐幾里得方程的形式 cas++; cout<<"Case "<<cas<<": "; ll ans=0; ///單獨討論特殊情況 if(a==0&&b==0) { if(c==0) cout<<(x2-x1+1)*(y2-y1+1)<<endl; else cout<<0<<endl; continue; } else if(a==0&&b!=0) { if(c%b==0) { ll tmp=c/b; if(y1<=tmp&&tmp<=y2) ans=x2-x1+1; } cout<<ans<<endl; continue; } else if(a&&b==0) { if(c%a==0) { ll tmp=c/a; if(x1<=tmp&&tmp<=x2) ans=y2-y1+1; } cout<<ans<<endl; continue; } exgcd(a,b,gcd,x,y); if(c%gcd) { cout<<0<<endl; continue; }///如果c不是gcd的倍數則無整數解 ll x0=x*c/gcd; ll y0=y*c/gcd; ll b1=b/gcd; ll a1=a/gcd; ll tx1,tx2,ty1,ty2; if(b*gcd>=0) { tx1=ceil(1.0*(x1-x0)/b1);//左邊界向右取整 tx2=floor(1.0*(x2-x0)/b1);//右邊界向左取整 } else { tx1=ceil(1.0*(x2-x0)/b1); tx2=floor(1.0*(x1-x0)/b1); } if(a*gcd>=0) { ty1=ceil(1.0*(y0-y2)/a1); ty2=floor(1.0*(y0-y1)/a1); } else { ty1=ceil(1.0*(y0-y1)/a1); ty2=floor(1.0*(y0-y2)/a1); } ll l=max(tx1,ty1); ll r=min(tx2,ty2); if(l>r) cout<<0<<endl; else cout<<r-l+1<<endl; } return 0; }