给定 G,求有多少个满足 K + (K + 1) + (K + 2) + \dots + (K + N - 1) = G 的正整数 K。
思路
十年 OI 一场空,不开【】见祖宗。
上面的柿子可以用求和公式转化成 NK + \frac{N(N - 1)}{2} = G。\
再移个项可以得到 NK = G - \frac{N(N - 1)}{2}。\
两边除以 N 得 K = \frac{G}{N} - \frac{N - 1}{2},通分得 K = \frac{2G - N^2 + N}{2N}。
因为 K \ge 1,所以 \frac{2G - N^2 + N}{2N} \ge 1。\
又因为 2N \ge 0,则 2G - N^2 + N \ge 2N,即 N^2 + N \le 2G。\
再配个方可以得到 N^2 + N + \frac{1}{4} \le 2G + \frac{1}{4},即 (N + \frac{1}{2})^2 \le \frac{8G + 1}{4}。\
因为 N + \frac{1}{2} \ge 0,所以 N + \frac{1}{2} \le \frac{\sqrt{8G + 1}}{2}。\
依旧移项得 N \le \frac{\sqrt{8G + 1} - 1}{2}。
所以 N 的范围是 1 \le N \le \frac{\sqrt{8G + 1} - 1}{2},只需要把每个 N 都枚举一遍然后看那个对应的 K 是整数。
判断 K 是不是整数只需要判断 2G - N^2 + N 能不能被 2N 整除。
十年 OI 一场空,不开【】见祖宗。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t, g, cnt;
signed main()
{
scanf("%lld", &t);
for (int i = 1; i <= t; i++)
{
scanf("%lld", &g), cnt = 0;
for (int n = 1; n <= (sqrt(8 * g + 1) - 1) / 2; n++)
if ((2 * g - n * n + n) % (2 * n) == 0)
cnt++;
printf("Case #%lld: %lld\n", i, cnt);
}
return 0;
}