sgu 106 The equation

题意:给出式子,问x,y在范围内的解的个数。

1:如果a==0&&b==0,c==0有解,否则无解。

2.否则(本题没有a==0或者b==0的数据) a!=0&&b!=0。用ex_gcd得出,abs(a)x+abs(b)y==gcd(abs(a),abs(b)),时x,y的特解,记d=gcd(abs(a),abs(b))。用-c/d乘x,y得到abs(a)x+abs(b)y==-c的特解。如果a<0,x*=-1,b<0,y*=-1,得到ax+by==-c的特解。记为x0,y0。a,b同号的情况下,x0+k(b/d),y0-k(a/d)还是解。那么就看两者k各能取多少,得出交集就行了。具体来说,x0+k(b/d)>=x1,x0+k(b/d)<=x2得出k的取值[kx1,kx2],再得出[ky1,ky2]取交。注意在>=且b>=0时,向上取整

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=120,INF=0x7FFFFFFF;

void ex_gcd(lon &x,lon &y,lon a,lon b,lon &d)
{
    if(b==0)
    {
        d=a;
        x=1,y=0;
        return;
    }
    ex_gcd(y,x,b,a%b,d);
    y-=a/b*x;
}

lon func(lon sgn,double val,lon g)
{
    return (!((sgn>0)^g))?ceil(val):floor(val);
}

int main()
{
    //cout<<ceil(-10.3)<<endl;
    std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    lon a,b,c,x1,x2,y1,y2,x,y,d;
    cin>>a>>b>>c>>x1>>x2>>y1>>y2;
    if(a==0&&b==0)
    {
        if(c==0)cout<<((x2-x1+1)*(y2-y1+1))<<endl;
        else cout<<0<<endl;
    }
    else if(b==0)
    {
        //if(c/a==(lon)(1.0*c/a))cout<<1<<endl;
        //else cout<<0<<endl;
    }
    else
    {
        c*=-1;
        ex_gcd(x,y,abs(a),abs(b),d);
        //cout<<x<<" "<<y<<endl;
        if(c%d)
        {
            cout<<0<<endl;
        }
        else
        {
            x*=c/d;
            y*=c/d;
            if(a<0)x*=-1;
            if(b<0)y*=-1;
            //cout<<x<<" "<<y<<endl;
            lon addx=b/d,addy=-a/d;
            //cout<<addx<<" "<<addy<<endl;
            lon kx1=func(addx,1.0*(x1-x)/addx,1);
            lon kx2=func(addx,1.0*(x2-x)/addx,0);
            lon ky1=func(addy,1.0*(y1-y)/addy,1);
            lon ky2=func(addy,1.0*(y2-y)/addy,0);
            //cout<<" "<<addy<<" "<<1.0*(y2-y)/addy<<endl; 
            if(addx<0)swap(kx1,kx2);
            if(addy<0)swap(ky1,ky2);
            //cout<<kx1<<" "<<kx2<<" "<<ky1<<" "<<ky2<<endl;
            lon res1=max(kx1,ky1),res2=min(kx2,ky2);
            cout<<max(0LL,res2-res1+1)<<endl;
        }
    }
    return 0;
}

还有其他情况。

猜你喜欢

转载自www.cnblogs.com/gaudar/p/9754118.html
sgu
106