1 条题解
-
0
自动搬运
来自洛谷,原作者为

xyz32768
“各方面相差太远”搬运于
2025-08-24 21:46:05,当前版本为作者最后更新于2017-10-22 10:53:21,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
首先,进行如下处理:
1、如果是的倍数,那么把变为,否则变为。
2、把变成。
这样子容易得出,现在要求的就是在之间,选数次使选出的数最大公约数为的方案数。
现在,用表示选出的数的最大公约数且选出的数不全相同的方案数。此时先求出之间的倍数的个数,暂时令。
但此时得到的实际上是含有公约数的方案数,不是最大公约数为的方案数。但是可以发现,此时的包含有最大公约数为的方案数。这时候使用容斥原理:假设已经知道了的最终结果,那么就把分别减去,就可以得到的最终结果。倒着推一遍。
特殊情况:时可以所有的数都选。所以时答案要加。
代码:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; inline int read() { int res = 0; bool bo = 0; char c; while (((c = getchar()) < '0' || c > '9') && c != '-'); if (c == '-') bo = 1; else res = c - 48; while ((c = getchar()) >= '0' && c <= '9') res = (res << 3) + (res << 1) + (c - 48); return bo ? ~res + 1 : res; } const int N = 1e5 + 5, PYZ = 1e9 + 7; int n, K, L, H, f[N]; int qpow(int a, int b) { int res = 1; while (b) { if (b & 1) res = 1ll * res * a % PYZ; a = 1ll * a * a % PYZ; b >>= 1; } return res; } int main() { int i, j; n = read(); K = read(); L = read(); H = read(); if (L % K) L = L / K + 1; else L /= K; H /= K; if (L > H) return puts("0"), 0; for (i = 1; i <= H - L; i++) { int l = L, r = H; if (l % i) l = l / i + 1; else l /= i; r /= i; if (l > r) continue; f[i] = (qpow(r - l + 1, n) - (r - l + 1) + PYZ) % PYZ; } for (i = H - L; i; i--) for (j = (i << 1); j <= H - L; j += i) f[i] = (f[i] - f[j] + PYZ) % PYZ; if (L == 1) (f[1] += 1) %= PYZ; cout << f[1] << endl; return 0; }
- 1
信息
- ID
- 2245
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者