AtCoder ABC 165 D - Floor Function (Good, 手动模拟推出公式)
题目链接:Here
题意:
给出正整数 \(A,B,N (1\le A\le 1e6,1\le B,N\le1e12)\) ,对于 \(x\in [0,N]\) 求出
- \(\left\lfloor\frac{A x}{B}\right\rfloor-A \times\left\lfloor\frac{x}{B}\right\rfloor\)
的最大值
\[QAQ
\]
全搜索的话 \(\mathcal{O}(n)\) 的时间复杂度是肯定不行的,直接看过去公式应该能够化简,
如果不是 \(floor\) (向下取整) ,而是实数运算的话, \(\frac{Ax}B - \frac{Ax}B = 0\) 就恒成立了
大概如上思考的话,总觉得为了使 \(x\) 这个值更大,原公式后面部分的 \(\left\lfloor\frac{x}{B}\right\rfloor\) 应该尽可能的靠近向上取整得到的整数,即尽可能得到 \((.999999)\) 这样的答案,此时差值就变大起来了
实际模拟一下
样例一:\(A=5,B=7,N=4\)
\(x\) | \(\left\lfloor\frac{A x}{B}\right\rfloor\) | \(A \times\left\lfloor\frac{x}{B}\right\rfloor\) | 差值 |
---|---|---|---|
0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 |
2 | 1 | 0 | 1 |
3 | 2 | 0 | 2 |
4 | 2 | 0 | 2 |
5 | 3 | 0 | 3 |
6 | 4 | 0 | 4 |
7 | 5 | 5 | 0 |
8 | 5 | 5 | 0 |
9 | 6 | 5 | 1 |
10 | 7 | 5 | 2 |
11 | 7 | 5 | 2 |
12 | 8 | 5 | 3 |
13 | 9 | 5 | 4 |
而且要注意的是:
- \(A \times\left\lfloor\frac{x}{B}\right\rfloor\) 是周期的增加,\(B(=7),A(=5)\)
同理:\(\left\lfloor\frac{A x}{B}\right\rfloor\) 也是一样的
\(f(x) = \left\lfloor\frac{A x}{B}\right\rfloor-A \times\left\lfloor\frac{x}{B}\right\rfloor\) 的取值对于 \(B\) 来说是周期性的,所以 \(x\) 的取值
- \(x=0,1,2,...,B-1\)
考虑这么多即可
在 \(x = 0,1,2,...,B-1\) 的范围中
- \(\left\lfloor\frac{A x}{B}\right\rfloor\) 单调递增
- \(A \times\left\lfloor\frac{x}{B}\right\rfloor\) 保持不变
- 那么 \(f(x)\) 单调性也就是同 \(\left\lfloor\frac{A x}{B}\right\rfloor\) 一样单调递增了
换句话说,只要满足
- \(x=0,1,...,B-1\)
- \(x\le N\)
的话符合条件的最大 \(x\) 应该是 \(x=\min(N,B-1)\)
那么最后答案输出 $ \frac AB\times \min(N,B-1)$ 即可
时间复杂度由全搜索的 \(\mathcal{O}(n) \to \mathcal{O}(1)\)
ll a, b, n;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
cin >> a >> b >> n;
cout << a * min(n, b - 1) / b;
}