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;
}
完结撒花~
浙公网安备 33010602011771号