D-青蛙兔子的约会_牛客练习赛111 (nowcoder.com)
题意:

思路:
感觉和那个青蛙的约会比较像
就是列了个方程:
a*x+b*y=n
考虑用exgcd解方程
然后看x在[L,R]有没有解
做法就是先把x的最小整数解求出来,然后考虑它的通解
x=x0+b/d*t
暴力枚举t肯定不行,因为看数据范围是1e9,因此考虑O(1)算
一种做法是根据相对位置,将L和R都减去x,然后去看L和R之间有没有k*p
这个比较细节

比较这两处的l和r即可
如果l<=r就是有解,否则就是无解
Code:
#include <bits/stdc++.h>
#define int long long 
using namespace std;
const int mxn=2e6+10; 
const int mod=1e9+7;
int a,b,n,L,R,x,y;
int exgcd(int a,int b,int &x,int &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	int d=exgcd(b,a%b,y,x);
	y-=(a/b)*x;
	return d;
}
int ceil(int x,int y){
	return (x+y-1)/y;
}
void solve(){
	cin>>a>>b>>n>>L>>R;
	int d=exgcd(a,b,x,y);
	if(n%d!=0){
		cout<<"NO"<<'\n';
		return;
	}
	int p=b/d;
	x=(x*n/d)%p;
	x=(x%p+p)%p;
	int l=L-x;
	if(l<0) l=0;
	else l=(L-x+p-1)/p;
	int r=R-x;
	if(r<0) r=-1;
	else r=(R-x)/p;
	if(l<=r) cout<<"YES"<<'\n';
	else cout<<"NO"<<'\n';
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int __=1;cin>>__;
	while(__--)solve();return 0; 
}  
还有一种做法就是:
如果把次数x设成从0开始,那么是不是看x在不在r-l之内就行
那就在求exgcd之前青蛙先走L次,这样次数就是从0开始了,这样就是判断次数在不在[0,r-l]之间
Code:
#include <bits/stdc++.h>
#define int long long 
using namespace std;
const int mxn=2e6+10; 
const int mod=1e9+7;
int a,b,n,L,R,x,y;
int exgcd(int a,int b,int &x,int &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	int d=exgcd(b,a%b,y,x);
	y-=(a/b)*x;
	return d;
}
void solve(){
	cin>>a>>b>>n>>L>>R;
	n-=L*a;
	int d=exgcd(a,b,x,y);
	if(n%d!=0){
		cout<<"NO"<<'\n';
		return;
	}
	x*=n/d;
	y*=n/d;
	int t=b/d;
	int ans=(x%t+t)%t;
	if(ans<=R-L) cout<<"YES"<<'\n';
	else cout<<"NO"<<'\n';
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int __=1;cin>>__;
	while(__--)solve();return 0; 
}  
                


















