1 条题解
-
0
题目重述
给定正整数 ,要求找到所有满足
的不同 值的个数,其中 都是非负整数。
核心思想
由等式 可得:
因此, 必须是整数,即 必须能整除 。
关键观察
-
和 的范围有限
- 因为 ,当 增大时, 增长很快。
- 已经超过 的最大值 。
- 所以 最多到 左右, 同理。
- 标程中用了 作为上限( 很多,足够安全)。
-
枚举所有可能的 组合
- 先固定 ,从 中除去 得到中间值 。
- 然后从这个中间值中不断除去 的幂次,得到不同的 。
- 用
set自动去重。
标程详解
void solve(int tc){ int a, b, l; cin >> a >> b >> l; set<int> ans; for(int i = 0; i <= 34; ++i){ // i 表示 x 的值 int x = l; bool fail = false; // 从 l 中除去 a^i for(int _ = 0; _ < i; ++_){ if(x % a){ // 如果不能整除,说明这个 i 不可行 fail = true; break; } x /= a; } if(fail) break; // 如果 a^i 不能整除 l,更大的 i 也不行 // 现在 x = l / a^i // 不断从 x 中除去 b 的幂次,得到不同的 k while(true){ ans.insert(x); // 当前 x 就是一个可行的 k if(x % b) break; // 如果不能继续除 b,就停止 x /= b; } } cout << ans.size(); }
算法流程示例
以第一个样例 为例:
-
():,然后不断除 :
- ,,除以 得
- ,,停止
-
():,然后除 :
- ,,除以 得
- ,,停止
-
():,除 :
- ,,除以 得
- ,,停止
-
: 不是整数,失败,循环结束
最终 ,共 个。
复杂度分析
- 外层循环 最多 次
- 内层每次最多除 约 次
- 总复杂度 ,非常快
总结
关键点:
- 注意到 的取值范围很小( 到约 )
- 枚举所有可能的 ,然后从 中不断除去 的幂次
- 用集合自动去重
这种方法简单高效,完全满足题目 的限制。
-
- 1
信息
- ID
- 6504
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者