SGU 106. The equation 扩展欧几里德

求解的个数

对应ax+by=c 根据裴蜀定理c%gcd(a, b) == 0有解 假设d = gcd(a, b)

用扩展欧几里德求出方程aax+bb*y=cc 的解x0 y0

那么原方程的一个解就是x0*c/d和y0*c/d

通解为

x = x0+i*b/d

y = y0+i*a/d

分别讲x1 x2 带入得到i 满足最小的左区间 y1 y2一样

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
//求整数x和y,使得ax+by=d, 且|x|+|y|最小。其中d=gcd(a,b)
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 -= x * (a/b);
	}
}
int main()
{
	LL a, b, c, x1, x2, y1, y2;
	//scanf("%lld %lld %lld %lld %lld %lld %lld", &a, &b, &c, &x1, &x2, &y1, &y2);
	scanf("%I64d %I64d %I64d %I64d %I64d %I64d %I64d", &a, &b, &c, &x1, &x2, &y1, &y2);
	c = -c;
	if(a == 0 && b == 0)
	{
		if(c == 0)
			printf("%lld\n", (x2-x1+1)*(y2-y1+1));
		else
			puts("0");
	}
	else if(!a && b)
	{
		if(c%b == 0 && y1 <= c/b && y2 >= c/b)
			puts("1");
		else
			puts("0");
	}
	else if(a && !b)
	{
		if(c%a == 0 && x1 <= c/a && x2 >= c/a)
			puts("1");
		else
			puts("0");
	}
	else
	{

		LL x, y, d;
		gcd(a, b, d, x, y);
		if(c%d)
			puts("0");
		else
		{

			//x = x0 + b/d*k;
			//y = x1 - a/d*k
			LL k1, k2, k3, k4, mi, ma;
			if(b/d > 0)
			{
				LL p = b/d;
				k1 = (x1-x*(c/d))/(b/d);
				k2 = (x2-x*(c/d))/(b/d);
				if(x*(c/d)+p*k1 < x1)
					k1++;
				if(x*(c/d)+p*k2 > x2)
					k2--;
				mi = k1;
				ma = k2;
			}
			else
			{
				LL p = -b/d;
				k1 = (-x2+x*(c/d))/(-b/d);
				k2 = (-x1+x*(c/d))/(-b/d);
				if(-x*(c/d)+p*k1 < -x2)
					k1++;
				if(-x*(c/d)+p*k2 > -x1)
					k2--;
				mi = k1;
				ma = k2;
			}
			if(-a/d > 0)
			{
				LL p = -a/d;
				k3 = (y1-y*(c/d))/(-a/d);
				k4 = (y2-y*(c/d))/(-a/d);
				if(y*(c/d)+p*k3 < y1)
					k3++;
				if(y*(c/d)+p*k4 > y2)
					k4--;
				mi = max(mi, k3);
				ma = min(ma, k4);
			}
			else
			{
				LL p = a/d;
				k3 = (-y2+y*(c/d))/(a/d);
				k4 = (-y1+y*(c/d))/(a/d);
				if(-y*(c/d)+p*k3 < -y2)
					k3++;
				if(-y*(c/d)+p*k4 > -y1)
					k4--;
				mi = max(mi, k3);
				ma = min(ma, k4);
			}
			//printf("%I64d %I64d\n", k3, k4);
			LL ans = ma-mi+1;
			if(ans < 0)
				ans = 0;
			printf("%lld\n", ans);
		}
	}
	return 0;
}
/*
1 1 -100000000
0 100000000
0 100000000
*/
时间: 2024-11-02 23:39:48

SGU 106. The equation 扩展欧几里德的相关文章

数论 + 扩展欧几里得 - SGU 106. The equation

The equation Problem's Link Mean: 给你7个数,a,b,c,x1,x2,y1,y2.求满足a*x+b*y=-c的解x满足x1<=x<=x2,y满足y1<=y<=y2.求满足条件的解的个数. analyse: 做法是扩展欧几里德. 1.首先是欧几里德算法,欧几里德算法是用于求任意两个数的最大公约数(gcd(a,b)), 这个方法基于一个定理,gcd(a,b)=gcd(b,a % b)(a>b),%表示取模. 我们来证明上述定理,因为a>b,

SGU 106 The equation

我的思路就是首先把一个基本解求出来,然后看在x1.x2的范围内x的范围是多少,然后找到对应的y的范围,再看y的范围有多少个解是在y1.y2范围之内的,这个就是最后的答案. 当然,对于含有a=0或b=0的情况要特判一下. #include <iostream> using namespace std; typedef long long LL; LL a,b,c,x1,x2,y1,y2,x,y,tmp,ans=0; LL mini = -361168601842738790LL; LL maxi

扩展欧几里德算法

文章来源:http://blog.csdn.net/zhjchengfeng5/article/details/7786595 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了

POJ2142 The Balance (扩展欧几里德)

本文为博主原创文章,欢迎转载,请注明出处 www.cnblogs.com/yangyaojia The Balance 题目大意  你有一个天平(天平左右两边都可以放砝码)与重量为a,b(1<=a,b<=10000)的两种砝码.让你求出一种方案称出重为c(1<=c<=50000)的物品,如有多种方案,请输出两种砝码需要数量的总和最小的方案. 输入 有若干行,每行三个数,a,b,c. 结束时用0 0 0表示. 输出 若干行,每行两个数,表示每个询问中a的数量与b的数量 如果无解输出 

欧几里德与扩展欧几里德算法(转)

欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 第一种证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r 因此d是(b,a mod b)的公约数 假设d 是(b,a mod b)的公约数,则 d | b , d |r ,但是a

欧几理德,扩展欧几里德和模线性方程组。

欧几里德算法: 即求两个整数的最大公约数的一种快捷算法.也就是通常所说的“辗转相除法”.给定两个整数 a, b.欧几里德最坏可以在log(max(|a|, |b|))的复杂度内求出a, b的最大公约数.时间复杂度的计算方法也很有意思, 详见<算法导论>. 证明欧几里德算法的正确性: a可以表示成a = kb + r,且 r = a mod b 我们要证明欧几里德算法的正确性 也即是证明 gcd(a, b) = gcd(b, a%b=r) 假设d是a,b的一个公约数,则有 d|a, d|b,而r

HDU 1098 Ignatius&#39;s puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

POJ 2891-Strange Way to Express Integers(扩展欧几里德)

题目地址:POJ 2891 题意:给你k组同余关系,每组包含一个ai和ri,让你找出一个最小的数m,满足m%a1=r1,m%a2=r2.......m%ak=rk. 思路:纵观上述公式,很熟悉,其实就是求两两公式之间的最小值,例如K=3,那么先求第一组和第二组的最小,然后合并第一组和第二组,然后用合并之后的再和第三组找最小,最后的结果就是最终的结果.也就是这个题分两部分来完成. 1.找出两组最小.对于m%a1=r1和m%a2=r2可以得出两个公式m=a1*x+r1,m=a2*y+r2(x,y相当

HDU 2669 Romantic(扩展欧几里德)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2669 Problem Description The Sky is Sprite. The Birds is Fly in the Sky. The Wind is Wonderful. Blew Throw the Trees Trees are Shaking, Leaves are Falling. Lovers Walk passing, and so are You. ..........