构造 - Plus and Multiply - CF 1542B

构造 - Plus and Multiply - CF 1542B

题意:

给定一个无限集合,生成的规则如下:

  • 1 在其中。
  • 如果 x 在其中,则 x · a 和 x + b 也在。

给定正整数 n,a,b,请确定 n 是否在这个集合中。

输入:

t(1 ≤ t ≤ 105) :测试的 case 数量。

n, a, b(1 ≤ n, a, b ≤ 109)

输出:

Yes Or No

Example
input

5
24 3 5
10 3 6
2345 1 4
19260817 394 485
19260817 233 264

output

Yes
No
Yes
No
Yes

分析:

可以推断出,该集合中的数都可以写成形如:

X k = a i + b ⋅ j X_k=a^i+b·j Xk=ai+bj

的格式。

集合中任意的数 X k X_k Xk b b b 取模,得到 X k %   b = a i   %   b = m o d k X_k \% \ b=a^i\ \% \ b=mod_k Xk% b=ai % b=modk

我们假设 a i a^i ai [ 1 , n ] [1,n] [1,n] 中最小的,满足 a i   %   b = m o d k a^i \ \%\ b=mod_k ai % b=modk 的数,那么所有的,对 b b b 取模,且结果为 m o d k mod_k modk 的数,都可以由 a i a^i ai 加上若干多个 b b b 得到。

因此,若 n n n 在该集合中,那么该集合中必然存在一个不超过 n n n 的数 a i a^i ai,满足 a i   %   b = n   %   k a^i \ \%\ b=n\ \%\ k ai % b=n % k

结论: 只要我们在区间 [ 1 , n ] [1,n] [1,n] 中找到最小的满足条件的 a i a_i ai 就输出 Yes,否则输出 No。

注意: 因为我们要枚举指数,所以要特判 a = 1 a=1 a=1 的情况。

思考: 同样地,我们应该也能对 a a a 取模。但是,这样做我们要枚举 b ⋅ j b·j bj,这是相对有难度的。

代码:

#include<cstdio>

using namespace std;
typedef long long ll;

int T, a, b, n;

bool solve()
{
	if(a == 1) return (n - 1) % b == 0;
	
	ll pow_a = 1;
	while(pow_a <= n)
	{	
		if(pow_a % b == n % b)
			return true;
		pow_a = pow_a * a;
	}
	return false;
}

int main()
{
	scanf("%d", &T);
	while(T --)
	{
		scanf("%d%d%d", &n, &a, &b);
		puts(solve() ? "Yes" : "No");
	}
	
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值