SGU106

题目大意:

给定a,b,c,x1,x2,y1,y2

求解二元一次不定方程

ax+by+c=0

x∈[x1,x2],y∈[y1,y2]的解的个数


看到二元一次不定方程就想到扩展Euclid

只不过这道题确实很猥琐……十分容易WA,RE……

Calc函数是借鉴的别人的,我到现在都不明白我的方法为什么会wa……

//Lib
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
using namespace std;
//Macro
#define rep(i,a,b) for(int i=a,tt=b;i<=tt;++i)
#define rrep(i,a,b) for(int i=a,tt=b;i>=tt;--
#define erep(i,e,x) for(int i=x;i;i=e[i].next)
#define irep(i,x) for(__typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define read() (strtol(ipos,&ipos,10))
#define sqr(x) ((x)*(x))
#define pb push_back
#define PS system("pause");
typedef long long ll;
typedef pair<int,int> pii;
const int oo=~0U>>1;
const double inf=1e20;
const double eps=1e-6;
string name="",in=".in",out=".out";
//Var
ll a,b,c,x1,yy1,x2,y2,ans,x,y,t1,t2,k,kx1,kx2,kyy1,ky2,l,r,m;
bool In(ll a,ll b,ll c){return c>=a&&c<=b;}
ll ext_gcd(ll a,ll b,ll &x,ll &y)
{
	if(b==0)
	{
		x=1;y=0;
		return a;
	}
	ll ret=ext_gcd(b,a%b,x,y);
	ll t=x;
	x=y;y=t-a/b*x;
	return ret;
}
void Calc(ll l,ll r,ll x,ll t,ll &kl,ll &kr)
{
	if(t>0)
		l=l-x,r=r-x;
	else
	{
		kl=x-r;kr=x-l;
		l=kl;r=kr;
		t=-t;
	}
	kl=l/t;kr=r/t;
	if(l>=0&&l%t)kl++;
	if(r<0&&r%t)kr--;
}
void Work()
{
	cin>>a>>b>>c;c=-c;
	cin>>x1>>x2>>yy1>>y2;
	if(a==0||b==0)
	{
		if(a==0&&b==0)
		{if(c==0)ans=(x2-x1+1)*(y2-yy1+1);}
		else if(a==0)
		{
			if(c%b==0)
				if(In(yy1,y2,c/b))ans=x2-x1+1;
		}
		else if(b==0)
		{
			if(c%a==0)
				if(In(x1,x2,c/a))ans=y2-yy1+1;
		}
		cout<<ans<<endl;
		return;
	}
	m=ext_gcd(abs(a),abs(b),x,y);
	if(a<0)x=-x;if(b<0)y=-y;
	if(c%m!=0){cout<<0<<endl;return;}
	x*=c/m;y*=c/m;t1=b/m;t2=a/m;
	Calc(x1,x2,x,t1,kx1,kx2);
	Calc(yy1,y2,y,-t2,kyy1,ky2);
	l=max(kx1,kyy1);r=min(kx2,ky2);
	if(l<=r)cout<<r-l+1<<endl;
	else cout<<0<<endl;
}
int main()
{
//	freopen((name+in).c_str(),"r",stdin);
//	freopen((name+out).c_str(),"w",stdout);
//	Init();
	Work();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值