The equation SGU - 106

Topic links: https://codeforces.com/problemsets/acmsguru/problem/99999/106

This problem is particularly good EXGCD about a topic. Effect Title: An equation of the integer number of solutions of the equation ax + by + c = 0, inputs a, b, c and a range of l1, r1 and the range b, l2, r2, output meets.

answer:

  ax + by + c = 0. This equation, first consider the special circumstances:

1, a = 0 && b = 0 & c = 0, x and y are any meet, so the answer to (r1-l1 + 1) * (r2-l2 + 1)

2, a = 0 && b = 0, direct output 0

3, a = 0, the equation is converted by = -c, c is determined whether the multiple b is not 0, then output directly. Is then determined in a range of y, if (l2, r2), the answer is (r1-l1 + 1) b = 0 Similarly.

4, ax + by = -c. Try to make a and b are greater than 0. If a <0, then it will become a positive, then a change in the range of like a, b probably about the same. C will move over, and to try to ensure greater than or equal to 0 -c

5, ax + by = c, solved with exgcd. First, if c is not a multiple of gcd (a, b), and no solution. Otherwise it will convert equation a1x + b1y = c1. a1 = a / gcd (a, b), b, c empathy. X can be determined by exgcd Solution Solution Set set to x0 + kb, y is y0-ka. Then seeking range according to the range of k.

6, we will use two functions floor and ceil when evaluated range. Wherein floor represents an integer rounding up the maximum (largest integer less than 4.9), ceil is rounded down, 3.1 --- 4 is greater than 3.1 if 4.9--4. Then take a small upper bound, lower bound can take large.

code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
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==0){
        x=1,y=0;
        return a;
    }
    ll d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
} 
int main()
{
    ll a, b, c;
    cin >> a >> b >> c;
    c=-c; 
    ll l1, r1, l2, r2;
    cin >> l1 >> r1 >> l2 >> r2;
    if (c < 0) {
        c = -c; a = -a; b = -b;
    }
    if (a < 0) {
        a = -a; l1 = -l1; r1 = -r1; swap(l1, r1);
    }
    if (b < 0) {
        b = -b; r2 = -r2; l2 = -l2; swap(r2, l2);
    }
    if (a == 0 && b == 0 && c == 0){
        cout << (r1 - l1 + 1) * (r2 - l2 + 1) << endl;
        return 0;
    }
    else if (a == 0 && b == 0) { cout << 0 << endl; return 0; }
    else if (b == 0) {
        if (c % b == 0 && (-c) / b <= r2 && (-c) / b >= l2) cout << r1 - l1 + 1 << endl;
        else cout << 0 << endl;
        return 0;
    }
    else if (a == 0) {
        if (c % a == 0 && (-c) / a <= r1 && (-c) / a >= l1) cout << r2 - l2 + 1 << endl;
        else cout << 0 << endl;
        return 0;
    }
    ll d = gcd(a, b);
    if (c % d != 0) puts("0");
    else {
        ll x,y;
//        c=-c;
        a/=d;b/=d;c/=d;
        exgcd(a,b,x,y);
        x=x*c;y=y*c;
//        cout<<a<<"--"<<b<<"=="<<c<<"--"<<d<<"==="<<x<<"--"<<y<<endl; 
        double rr1,ll1,rr2,ll2;
        rr1=double(r1);ll1=double(l1);
        rr2=double(r2);ll2=double (l2); 
        ll upx=floor((rr1-x)/b),downx=ceil((ll1-x)/b);
        ll upy=floor((y-ll2)/a),downy=ceil((y-rr2)/a);
        ll ans=min(upx,upy)-max(downx,downy)+1;
        cout<<(ans<0? 0:ans)<<endl;
    }
    return 0;
}

Supplementary Exgcd (int a, int b, int & x, int & y) knowledge:

Demonstrate: ax + by = gcd (a, b) k. First calculates ax + by = gcd (a, b), can be solved and then into k.

        bx+(a%b)y=gcd(b,a%b)。

   a% b = a- (a / b) * b (where except for integer division)

 Get into the open bx + ay- (a / b) * by = gcd (b, a% b) = gcd (a, b) = ax + by, and then the corresponding equivalent, x = y, y = x- ( a / b) * b * y

The solution set is determined x: x0 + kb, y: y0-ka

exgcd code:

void exgcd(int a,int b,int &x,int &y){
    if(b==0) {x=1,y=0}
    else {
        exgcd(a,b,x,y);
        int t=x;
        x=y;y=t-a/b*y;
    }
}

Exgcd还可以用来求解逆元。证明过程用到了同余方程即ax%b=c,也可记为ax=c(modb)当c等与1时,x就是a的逆元。

求解过程:ax-b*y=1,带入exgcd中,x就是a的逆元。

 

Guess you like

Origin www.cnblogs.com/Accepting/p/12581918.html