Educational Codeforces Round 184 (Rated for Div. 2)
妈的,被 Hack 数据搞了
考虑第 i-th 迭代的位置 p 与第 i+1-th 迭代的位置 p′. 对于 p′ 之前的每 y−1 个位置,都是上一轮迭代里的 p 个位置删掉一个形成的. 所以
p←p′+⌊y−1p′−1⌋p′←p−⌊yp⌋初始时,p=O(V). 我们直接考虑数论分块:
- 如果 y−1<V,那么对于第二行的式子而言,每次都会减去 yp>V,所以最多 O(V) 轮. 而又由于一式其实就是二式的 inverse,所以直接执行一式也就 O(V) 轮.
- 如果 y−1>V,那么 floor(y−1p′−1) 最多 O(p) 个值. 我们对于每一次步长 floor(y−1p′−1) 计算需要加多少次.
需要注意的是,有可能 floor(y−1p′−1)=0,这个时候需要及时退出. 时间复杂度 O(V)
AC Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <bits/stdc++.h> using ll = long long; constexpr ll N = 1e12, sk = 1e6;
ll x, y, k;
void run() { std::cin >> x >> y >> k; if (y == 1) return std::cout << "-1\n", void();
auto find = [&] { ll f = (k - 1) / (y - 1); return (f + 1) * (y - 1) - 1; };
for (; x > 0;) { ll r = find(); ll step = (k - 1) / (y - 1); if (step == 0) break;
ll d = (r - k + 1) / step + 1; d = std::min(d, x); k = k + step * d; x -= d;
if (k > N) return std::cout << "-1\n", void(); } std::cout << k << "\n"; }
int main() { std::cin.tie(0)->sync_with_stdio(0), std::cout.tie(0); int t; std::cin >> t; while (t--) run(); }
|
E-