P8348 「Wdoi-6」未知之花魅知之旅

题意简介

初始数对 \(( a , b )\),每次可将其一替换为二者之差或和,判断能否在保证任意时刻 \(a , b \geq k\) 的前提下得到数对 \(( x , y )\)

思路

注意到取和操作可通过两次取差操作抵消,故只进行取差操作。\(( a , b )\) 直接向 \(( x , y )\) 靠拢复杂度过高,考虑将两者化为恰 \(\geq k\) 的形式,判断此时是否相等即可,由裴蜀定理易知若存在合法方案则此形式唯一。

直接模拟减法操作复杂度仍不可接受,受辗转相除法启发,若 \(m - t \times n \geq k\),则取 \(m = m - t \times n\),注意两者相对顺序不能改变。

单次查询时间复杂度 \(\mathcal O(\log V)\)

Code

#include<iostream>
#include<algorithm>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
int T,a,b,x,y,k;
inline int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
        x=x*10+(c-'0'),c=getchar();
    return x*f;
}
int Gcd(int m,int n) 
{
    while(n) 
    {
        int r=m;
        m=n;
        n=r%n;
    }
    return m;
}
inline void Calc(int &m, int &n)
{
	while(1)
	{
		int flag=0,tmp=0;
		if(m<n) swap(m,n),flag=1;
		if(m-k<n)
		{
			if(flag) swap(m,n);
			break;
		}
		tmp=(m-k)/n,m-=tmp*n;
		if(tmp+flag&1) swap(m,n);
	}
}
int main()
{
    IOS;
    T=read();
    while(T--)
    {
        a=read(),b=read(),x=read(),y=read(),k=read();
        if(min({a,b,x,y})<k)
        {
            cout<<"no"<<'\n';
            continue;
        }
        Calc(a,b),Calc(x,y);
        cout<<(a==x&&b==y?"yes":"no")<<'\n';
    }
    return 0;
}

完结撒花~

posted @ 2025-11-17 21:55  FallingGardenia  阅读(22)  评论(0)    收藏  举报