专栏文章
题解:CF2008H Sakurako's Test
CF2008H题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min0y6ig
- 此快照首次捕获于
- 2025/12/01 18:46 3 个月前
- 此快照最后确认于
- 2025/12/01 18:46 3 个月前
CF2008H
我们考虑对于每一个给定的 ,二分答案。
对于我们二分到的每一个答案 ,我们考虑最终可以变得小于等于 的数字数量是否大于等于 。
这个部分我们直接用前缀和统计即可。
但是我们需要注意对每一个出现过的 记录答案,这样可以将时间复杂度控制在 。
CPP#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int T, n, q, cnt[2 * N], ans[N];
bool Check(int t, int x) {
int ret = 0;
for (int i = 0; i * t <= n; i++) {
ret += cnt[i * t + x] - cnt[max(0, i * t - 1)];
if (ret >= (n + 2) / 2) return 1;
}
return 0;
}
void Solve() {
cin >> n >> q;
for (int i = 1, x; i <= n; i++) cin >> x, cnt[x]++;
fill(ans + 1, ans + n + 1, -1);
for (int i = 1; i <= 2 * n; i++) cnt[i] += cnt[i - 1];
while (q--) {
int x; cin >> x;
if (ans[x] != -1) {
cout << ans[x] << ' ';
continue;
}
int l = 0, r = x - 1;
while (l < r) {
int mid = (l + r) >> 1;
Check(x, mid) ? r = mid : l = mid + 1;
}
ans[x] = l, cout << l << ' ';
}
cout << '\n';
fill(cnt + 1, cnt + 2 * n + 1, 0);
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> T;
while (T--) Solve();
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...