1 条题解
-
0
一、题意理解
我们要求是否存在正整数 ,使得在 进制下, 的数位和 满足: 其中 给定。
二、初步观察
设 是正整数,。
在 进制下, 的数位和 有一个重要性质: 这是因为 ,所以 ,因此 的各位加权和模 等于数位和模 。
于是:
三、问题转化
我们要求: 利用上述同余性质,这等价于: 记 ,则必要条件为:
1. 必要条件
设 。
方程 有解当且仅当 。如果 ,则直接输出
No。
四、充分性讨论
如果 ,那么 有解 。
但是我们需要的是 ,而不仅仅是 。
实际上, 是严格成立的,所以: 而 ,所以 。
因此,如果 ,则 。
但我们要求模 ,而不仅仅是模 。
五、关键点
我们还需要 。
因为 ,所以 ,其中 。
条件 等价于: $ S_k(a n) \equiv c \pmod{g} \quad \text{且} \quad S_k(a n) \equiv c \pmod{r} $ 第一个条件已经由 保证(因为 )。
第二个条件 能否满足?
六、构造方法
已知 ,设 。
我们能否通过调整 使得 也成立?
注意 可以取很多不同的值,因为我们可以让 在 进制下包含很多高位,从而让数位和变化。
因此,我们可以通过加 来让数位和增加 。
因为 (因为 ,而 ,所以 ),所以 在模 下有逆元。
于是我们可以通过加若干个 来调整 模 的值,使其等于 。
七、结论
因此,充要条件就是: 即:
八、样例验证
样例1:
→No✅样例2:
→Yes✅
九、算法步骤
对每组数据:
- 计算
- 计算
- 如果 ,输出
Yes,否则输出No
复杂度 ,其中 是值域。
十、代码实现(C++)
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <climits> #include <algorithm> using namespace std; #define ll long long #define file(A) freopen(A, "r", stdin) #define mem(A, B) memset(A, B, sizeof(A)) #define max(a, b) (a > b ? a : b) #define min(a, b) (a < b ? a : b) inline ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); } inline ll p(ll a, ll k) { ll ans = 0; while (a) { ans += a % k; a /= k; } return ans; } int main(int argc, char *argv[]) { if (argc == 2 && !strcmp(argv[1], "local")) file("all.in"); int T; ll a, b, c, k; scanf("%d", &T); while (T--) { scanf("%lld %lld %lld %lld", &a, &b, &c, &k); if (c % gcd(b, gcd(p(a, k), k - 1)) == 0) printf("Yes\n"); else printf("No\n"); } return 0; }
十一、总结
本题的关键在于:
- 利用 进制数位和与数本身模 同余的性质。
- 将问题转化为线性同余方程的可解性问题。
- 发现充要条件是 。
- 利用构造法证明充分性。。
- 1
信息
- ID
- 4899
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者