牛客练习赛64 红色的樱花 exgcd 贪心

LINK:The red sakura

暴怒狂樱 血染京都.

这题质量不咋地 这题也没啥营养.

不过还是存在值得学习的地方的。

一个trick n行 m列 第一行与第n行相连 第1列和第m列相连的时候。

考虑一个有意思的事情 x+k,y+k 在gcd(n,m)==1的时候 x+k,y+k为整个网格的通项。

更普遍的 x+k,y+k所代表的集合 %gcd(n,m)为等价类.

那么容易发现 一共存在gcd(n,m)个等价类 每个等价类的大小为LCM(n,m);

考虑这道题 出题人的题解上说 可以证明最多使用一次1操作。

我也不会证明 感觉是对的吧。

那么容易得到 使用1操作的时间无所谓.

考虑如果不使用1操作 就是解两个同余方程.

如果使用 就是能否直接到达的问题 如果可以 就结束了 如果不行再解两个同余方程.

值得一提的是 第二个同余方程比较有意思 用的就是上述的算是引理吧.

ll T;
ll xx,yy;
inline ll exgcd(ll a,ll b)
{
	if(!b){xx=1;yy=0;return a;}
	ll ww=exgcd(b,a%b);
	ll zz=xx;xx=yy;yy=zz-a/b*yy;
	return ww;
}
inline ll solve(ll a,ll b,ll c,ll v)
{
	ll gcd=exgcd(a,b);
	if(c%gcd)return INF;
	b/=gcd;
	return (c/gcd*xx%b+b)%b*v;
}
inline ll G(ll a,ll b){return b?G(b,a%b):a;}
signed main()
{
	//freopen("1.in","r",stdin);
	get(T);
	while(T--)
	{
		ll get(n),get(m),get(d),get(sx),get(sy),get(ex),get(ey),get(a),get(b),get(c);
		--sx;--sy;--ex;--ey;
		if(sx==ex&&sy==ey){put(0);continue;}
		ll ans=INF;ll gcd=G(n,m);
		ans=min(ans,solve(d,n,(ex-sx+n)%n,b)+solve(d,m,(ey-sy+m)%m,c));
		ll w1=a+solve(d,gcd,ex-sx-(ey-sy),b);
		ll w2=a+solve(d,gcd,ey-sy-(ex-sx),c);
		ans=min(ans,w1);ans=min(ans,w2);
		if((sx-ex)%gcd==(sy-ey)%gcd)ans=min(ans,a);
		putl(ans==INF?-1:ans);
	}
	return 0;
}
posted @ 2020-05-24 16:20  chdy  阅读(148)  评论(0编辑  收藏  举报