题解:CF2089B2 Canteen (Hard Version)
题目很快就切了,全靠 tag 打的好。
做不出题怪大脑,胡出来题自称佬。
注意到答案上界为
考虑如何模拟过程中只模拟有意义操作,注意到可以用一个单调队列维护当前位置以及前面的
那有人就要问了,这只是 easy 版的做法,那 hard 版呢?莫慌莫慌,听我徐徐道来。我们可以二分答案,用上面的方法检验答案是否合法。这样时间复杂度为
code
#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;
}