【扩展欧几里得+解不等式】sgu106The equation

来源:互联网 发布:买家怎样取消淘宝客 编辑:程序博客网 时间:2024/05/17 00:17

题目链接
题目大意:对于一个不定方程ax+by+c=0,其中x[x1,x2]y[y1,y2]。求有多少组解。
数据范围:每一个数的绝对值不超过108

一道裸的扩展欧几里得。
首先将方程变式为ax+by=c,即c=c
假设a,b,c都是正数。
若求得一组解x,y,那么x=x+kb/d,y=yka/d则是另一组解。
要判断解的个数,就是计算有多少个k

对于x,(x1x)/(b/d)<=k<=(x2x)/(a/d)
对于y,(yy2)/(a/d)<=k<=(yy1)/(a/d)
然后再合并一下。

那么负数肿么办?
变为正数就行了。
取相反数,取值范围也取相反数。
在这里将负数变为正数是有必要的,若是负数,k的取值范围就要取反。如果不将负数变为正数,就进行分类讨论。

在解不等式时,注意上取整和下取整的问题,最好用floorceil函数。(蒟蒻就是在这里wa了无数遍)

#include <iostream>#include <cstdio>#include <cmath>using namespace std;typedef long long LL;void gcd(LL a,LL b,LL &d,LL &x,LL &y){    if(!b)        d=a ,x=1 ,y=0 ;    else    {        gcd(b,a%b,d,y,x);        y-=a/b*x;    }}LL a ,b ,c ,x1 ,x2 ,yy1 ,yy2 ;LL d ,x ,y ;int main(){    cin>>a>>b>>c>>x1>>x2>>yy1>>yy2;    c=-c;    if(c<0)        c=-c ,a=-a ,b=-b ;    if(a<0)        a=-a ,swap(x1,x2) ,x1=-x1 ,x2=-x2;    if(b<0)        b=-b ,swap(yy1,yy2) ,yy1=-yy1 ,yy2=-yy2 ;    if(a==0||b==0)    {        if(a==0&&b==0)        {            if(c==0)                cout<<(x2-x1+1)*(yy2-yy1+1);            else puts("0");        }        else if(a==0)        {            if(c%b==0&&c/b>=yy1&&c/b<=yy2)                cout<<x2-x1+1;            else puts("0");        }        else        {            if(c%a==0&&c/a>=x1&&c/a<=x2)                cout<<yy2-yy1+1;            else puts("0");        }        return 0;    }    gcd(a,b,d,x,y);    if(c%d)    {        puts("0");        return 0;    }    LL tmp=c/d ;    double addx=b/d ,addy=a/d ;    x*=tmp ,y*=tmp ;    LL r=min(floor((x2-x)/addx),floor((y-yy1)/addy)) ,l=max(ceil((x1-x)/addx),ceil((y-yy2)/addy)) ;    if(r>=l)        cout<<r-l+1;    else puts("0");    return 0;}
0 0
原创粉丝点击