Codeforce round #729 B题

B. Plus and Multiply

1 is in this set.
If x is in this set, x⋅a and x+b both are in this set.

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

1,
3 (1 is in this set, so 1⋅a=3 is in this set),
7 (1 is in this set, so 1+b=7 is in this set),
9 (3 is in this set, so 3⋅a=9 is in this set),
13 (7 is in this set, so 7+b=13 is in this set).
Given positive integers a, b, n, determine if n is in this set.

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

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

Output
For each test case, print “Yes” if n is in this set, and “No” otherwise. You can print each letter in any case.

B. 加和乘

1 在这个集合中。
如果 x 在这个集合中,x⋅a 和 x+b 都在这个集合中。
例如,当 a=3 和 b=6 时,集合的五个最小元素为:

1、
3(1在这个集合中,所以1⋅a=3在这个集合中),
7(1在这个集合中,所以1+b=7在这个集合中),
9(3在这个集合中,所以3⋅a=9在这个集合中),
13(7在这个集合中,所以7+b=13在这个集合中)。
给定正整数 a、b、n,确定 n 是否在这个集合中。

输入
输入由多个测试用例组成。 第一行包含一个整数 t (1≤t≤10^5)——测试用例的数量。 测试用例的描述如下。

描述每个测试用例的唯一一行包含三个整数 n, a, b (1≤n,a,b≤10^9) 由一个空格分隔。

输出
对于每个测试用例,如果 n 在这个集合中,则打印“Yes”,否则打印“No”。 您可以在任何情况下打印每个字母。

思想:
因为开始集合里面只有一个元素1,对集合中的任何一个元素,它可以乘以a 或者 加上b,然后再将这两个新的元素加入到集合中,所以第一次操作后,得到的两个元素为 a 和 b + 1,这两个元素加入到集合中,然后第二次操作就会得出四个元素

由a乘以a 和 由 a 加上b得来的以下两个:
a ^ 2 = a ^ 2 + 0 * b
a + b = a ^ 1 + 1 * b
由b + 1乘以a和由 b + 1加上b的来的以下两个:
a + a * b = a ^ 1 + a * b
1 + 2 * b = a ^ 0 + 2 * b

然后发现不论怎么操作,最终都可以得到这样元素通式:a ^ n + m * b
假设n在集合中,那么就有n = a ^ n + m * b,即(n - a ^ n) % b == 0 。 对于a ^ n + m * b这个元素来说,我们只看重一个地方,那就是a ^ n,因为在a ^ n + m * b中,不管m是多少,我们都可以通过a ^ n加上1,2,3,…,无限个b来得到。所以我们将a所有的幂全部求出来(a ^ i , i = 1, 2, 3, …, x 其中进行到a ^ x > n就结束)看看是否存在一个i使得 (n - a ^ i) % b == 0,如果存在那么n就在集合中,不存在则不在集合中。 注意:还需特判一下a = 1的情况,因为如果a = 1的时候,加入n不在集合中就会陷入死循环。

代码如下:

#include<iostream>
 
using namespace std;
 
int main()
{
    int t;
    cin >> t;
    while(t --){
        int n, a, b;
        scanf("%d%d%d", &n, &a, &b);
		if(a == 1){ //特判
			if((n - 1) % b == 0)    printf("Yes\n");
			else    printf("No\n");
			continue;
		}
        long long res = 1;
        int flag = 0;
        while(res <= n){
            if((n - res) % b == 0){
                flag = 1;
                break;
            }
            else    res *= a;
        }
        if(flag)    printf("Yes\n");
        else    printf("No\n");
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值