Plus and Multiply

There is an infinite set generated as follows:

  • 11 is in this set.
  • If xx is in this set, x⋅ax⋅a and x+bx+b both are in this set.

For example, when a=3a=3 and b=6b=6, the five smallest elements of the set are:

  • 11,
  • 33 (11 is in this set, so 1⋅a=31⋅a=3 is in this set),
  • 77 (11 is in this set, so 1+b=71+b=7 is in this set),
  • 99 (33 is in this set, so 3⋅a=93⋅a=9 is in this set),
  • 1313 (77 is in this set, so 7+b=137+b=13 is in this set).

Given positive integers aa, bb, nn, determine if nn is in this set.

Input

The input consists of multiple test cases. The first line contains an integer tt (1≤t≤1051≤t≤105) — the number of test cases. The description of the test cases follows.

The only line describing each test case contains three integers nn, aa, bb (1≤n,a,b≤1091≤n,a,b≤109) separated by a single space.

Output

For each test case, print "Yes" if nn is in this set, and "No" otherwise. You can print each letter in any case.

Input:

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

Out:

Yes
No
Yes
No
Yes

题意:原始集合中有元素 1 ,现有数字n , a , b。我们用集合中的元素乘以a,或加b 的方式构造数字,问能不能构造出n

思路:

  • 若a == 1时:集合中元素乘以a是不变的,因此这时只能用原来集合中的1,加上若干个b构造,如果n - 1 % b == 0,则可以构造,!= 0则相反。
  • 若a > 1:设当前乘完若干个a加完若干个b后数字是x(x = ((x + kb)*a + b)),看现在的x加上若干个b能不能构造出n,因此只要此时的n -  x % b == 0即可构造成功,不能的话,就要乘以a。x进入下一轮循环(加上若干b,再乘以a)。

关键:虽说可以任意顺序加b或者乘a,但事实上加若干b,有时是加0个b,所以就是*a + kb的顺序进行下去的 ,因此只需要判定n-x % b == 0即可,那为什么下列代码中是直接减去pow(a,j)再判断是否%b==0呢?

再看(x*a + k*b)*a = x*a^2 + k*a*b 注意到,后面省去的k*a*b,一定是可以由若干个b构成的,当

(n - x*a^2 )% b的时候还可以用若干k*a*b + k1*b来补齐剩余。

AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e5 + 10;

int a[N];

void solve(){
	int n,a,b; cin >> n >> a >> b;
	if(a == 1){
		if((n-1)%b==0)cout << "YES\n";
		else cout << "NO\n";
	}else{
		for(int j = 1;j <= n;j*=a){
			if((n - j) % b == 0){
				cout << "YES\n";
				return;
			}
		}
		cout << "NO\n";
	}
}

signed main(){
    int t; cin >> t;
	while(t--){
		solve();
	} 
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值