竞赛讨论区 > 一名菜鸟关于 D (斩杀线计算大师)题的理解
头像
A_luckly_boy
编辑于 2020-03-28 14:01
+ 关注

一名菜鸟关于 D (斩杀线计算大师)题的理解

首先,分析题意,很容易得到:
ax+by+cz == k
根据拓展欧几里得 ax+by==c ,很容易联想到本题的正解即为拓展欧几里得。
回顾下拓展欧几里得算法:   (如果我写错了,一定要告诉我。
已知:ax+by==c
据拓展欧几里得:ax+by==gcd(a,b)*k   (k为常数)
则:c == gcd(a,b)*k
即:k == c/gcd(a,b);
假定存在一组 (x0,y0),使得 ax0+by0 == gcd(a,b)
则:(ax0 + by0) * k == gcd(a,b) * k == c
所以:(x0*k,y0*k) 即为方程 ax+by == c 的一组解
此时我们已经找到了关于方程的解,但不能保证是整数。需要将答案置为整数
(按我这只菜鸟的理解) : ax + by == gcd(a,b) * k
(ax - at) + (by + at) == gcd(a,b) * k
此时: at 是 b 的整数倍(可负)。
关键是怎么找到这个 t 呢 。
令 u = b / gcd(a,b) , v = a / gcd(a,b)
y = y + ( ( (-y) / v ) * v) // 将 y 置为最接近 0 的位置
x = x - ( ( (-y) / v ) * u) //对应的 x 值
while(y<0) y += v,x -= u; // 将 y 置为 正数。
此时 就可以将 (x,y) 置为正整数了。
/****************************************华丽的分割线***************************************/
如果想明白拓展欧几里得,那么回到这一题。
ax+by+cz==k
题目保证有解,则:ax + by == k - cz
根据扩展欧几里得:ax + by == gcd(a,b) * p
此时原方程则为 gcd(a,b)p + cz == k
根据拓展欧几里得 可以解出 (p,z)
带入原方程为:ax + by = k - cz
再次使用拓展欧几里得 解出 (x,y).
此时,题目已经解决了 。
附上一份代码。如有错误,望指出:
struct GCD
{
	ll gcd(ll a,ll b)
	{
		if(a%b==0)return b;
		return gcd(b,a%b);
	}
	ll exgcd(ll a,ll b,ll &x,ll &y)
	{
		if(b==0)
		{
			x=1;
			y=0;
			return a;
		}
		ll r=exgcd(b,a%b,x,y);
		ll temp=x;
		x=y;
		y=temp-(a/b)*y;
		return r;
	}
	void init(ll a,ll b,ll k,ll &ansx,ll &ansy) //方程样式:ax + by == k 答案为 ansx,ansy
	{
		ll x,y;
		ll d = exgcd(a,b,x,y);
		x = x * (k / d) , y = y * (k / d);
		ll u = b/d ,v = a/d;
		ll coe = -y / v;
		y += coe * v ;
		x -= coe * u ;
		while(y<0) y+= v,x-=u;
		ansx = x;
		ansy = y;
	}
};
本人第一次写题解,如有错误,请一定说出来哇,不然就尴尬了😪

最后,我还是怕写错,如果有发现问题的大佬,一定要在下面说出来啊,支持下菜鸟,谢谢大佬!!!



全部评论

(3) 回帖
加载中...
话题 回帖

等你来战

查看全部

热门推荐