专栏文章
题解:CF2089B2 Canteen (Hard Version)
CF2089B2题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minlanhh
- 此快照首次捕获于
- 2025/12/02 04:16 3 个月前
- 此快照最后确认于
- 2025/12/02 04:16 3 个月前
题目很快就切了,全靠 tag 打的好。
做不出题怪大脑,胡出来题自称佬。
做不出题怪大脑,胡出来题自称佬。
注意到答案上界为 所以暴力模拟的操作次数为 次 ,不可接受。注意到对于每次操作的 和 其中必然有一个会清零,对于为零的值我们的操作实际上没有意义,所以我们本质上有意义的操作只有 次。
考虑如何模拟过程中只模拟有意义操作,注意到可以用一个单调队列维护当前位置以及前面的 。对于一个位置 ,要么 清零,要么 单调队列清空,操作次数只有 次,可以接受。
那有人就要问了,这只是 easy 版的做法,那 hard 版呢?莫慌莫慌,听我徐徐道来。我们可以二分答案,用上面的方法检验答案是否合法。这样时间复杂度为 ,可以通过。
code
CPP#include<bits/stdc++.h>
using namespace std;
#define N 200005
int n, a[N], b[N];
long long k;
inline bool check(int x) {
int aa[N], bb[N];
long long ret = 0;
deque<int> q;
for(int i = n; i; --i)
aa[i] = a[i], bb[i] = b[i];
for(int i = 1; i <= n; ++i) {
q.push_back(i);
while(!q.empty() && i - q.front() + 1 > x)
ret += aa[q.front()], q.pop_front();
if(ret > k) return 0;
while(!q.empty() && bb[i] >= aa[q.back()])
bb[i] -= aa[q.back()], q.pop_back();
if(!q.empty())
aa[q.back()] -= bb[i], bb[i] = 0;
}
for(int i = 1; !q.empty() && i <= n; ++i) {
while(!q.empty() && n - q.front() + i + 1 > x)
ret += aa[q.front()], q.pop_front();
if(ret > k) return 0;
while(!q.empty() && bb[i] >= aa[q.back()])
bb[i] -= aa[q.back()], q.pop_back();
if(!q.empty())
aa[q.back()] -= bb[i], bb[i] = 0;
}
return 1;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--) {
cin >> n >> k;
for(int i = 1; i <= n; ++i) cin >> a[i];
for(int i = 1; i <= n; ++i) cin >> b[i];
int l = 0, r = n;
while(l <= r) {
int mid = l + r >> 1;
if(check(mid)) r = mid - 1;
else l = mid + 1;
}
printf("%d\n", r + 1);
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...