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 
#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;
}

你可能感兴趣的:(codeforces补题,算法,acm竞赛,c++)