SGU 106 The equation ----扩展欧几里得

http://hi.baidu.com/lycanlancelot/item/8ad98b4aefeef8a4de2a9f53


方程ax+by+c=0;    问有多少对x,y. 满足 x1<=x<=x2, y1<=y<=y2

ax+by=-c. 

c=-c,后, 扩展欧几里得求一下,x,y;

x,y满足 ax+by=gcd(a,b);

x*=c/gcd(a,b);

y*=c/gcd(a,b);后

x,y满足 ax+by=c;

通解:

x0=x+k*b/gcd(a,b);

y0=y-k*a/gcd(a,b);

然后判断在范围中的对数。。

p=b/gcd()a,b;

x1<= x+k*p <=x2;

(x1-x)/p  <= k  <=  (x2-x)/p;

这里(x1-x)/p,  比如当(x1-x)<=0时,假如是-9,p=2,  那么值为 -9/2 = -4..     (-9<=k*2    -4<=k;)  满足条件。。

                                                                  假如是9,p=2,    那么值为9/2=4, (9<=k*2   4<=k)   不满足条件,应该值为5..

所以要特判一下边界问题,然后取交集。。


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll __int64

ll x,y;  
ll exgcd(ll a,ll b)  
{  
    if(b==0)  
    {  
        x=1,y=0;  
        return a;  
    }  
    ll gcd=exgcd(b,a%b);  
    ll t=x;  
    x=y;  
    y=t-a/b*y;  
    return gcd;  
}  
ll mod(ll a,ll b)  
{  
    if(a>=0)  
        return a%b;      //a%b,结果正负,只和a的正负有关  
    else  
        return a%b+abs(b); //b可能为负数。  
} 
int main()
{
	ll a,b,c,x1,x2,y1,y2;
	ll sum=0;
	cin>>a>>b>>c>>x1>>x2>>y1>>y2;
	c=-c;
	if(a==0&&b==0)
	{
		if(c==0)
			sum=(x2-x1+1)*(y2-y1+1);
	}
	else if(a==0)
	{
		if(c/b>=y1&&c/b<=y2&&c%b==0)
			sum=x2-x1+1;
	}
	else if(b==0)
	{
		if(c/a<=x2&&c/a>=x1&&c%a==0)
			sum=y2-y1+1;
	}
	else
	{
		ll g=exgcd(a,b);
		if(c%g==0)
		{
			x*=c/g;
			y*=c/g;
			ll p=b/g,q=a/g;
			ll lx=(x1-x>0&&(x1-x)%p!=0)?((x1-x)/p+1):((x1-x)/p);
			ll rx=(x2-x<0&&(x2-x)%p!=0)?((x2-x)/p-1):((x2-x)/p);
			ll ly=(y-y2>0&&(y-y2)%q!=0)?((y-y2)/q+1):((y-y2)/q);
			ll ry=(y-y1<0&&(y-y1)%q!=0)?((y-y1)/q-1):((y-y1)/q);
			if(lx>rx) swap(lx,rx);
			if(ly>ry) swap(ly,ry);
			if(rx>=ly&&ry>=lx)
			{
				ll mx=max(lx,ly);
				ll mn=min(rx,ry);
				sum=mn-mx+1;
			}
		}
	}
	cout<<sum<<endl;
	//system("pause");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值