You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
3.6 KiB

2 years ago
// https://www.jisuanke.com/problem/T3690
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10;
int a[N], b[N], c[N], n, k;
int T;
// ① 我喜欢的可以对于k变量每个贡献1的店铺
// ② 用一个大顶堆以访问需要的时长b[i]为权值保证这个堆的数量最多是k,那么堆顶的肯定花费时间更长的店,不划算的,准备放弃掉的店铺
priority_queue<int> q1;
// 被筛选下来的准备放弃掉的店铺放入到q2里
// 也是一个大顶堆
priority_queue<int> q2;
priority_queue<int, vector<int>, greater<int>> q3; // 小顶堆
LL res = -1; // 结果的默认值是-1
int sum1; // k个代价最小的店铺加在一起的总的访问花费时间。也就是q1中保留店铺的花费数字和
int sum2; // 被淘汰下来的店铺放在q2里q2中店铺的花费数字和
int main() {
freopen("street.in", "r", stdin);
freopen("street.out", "w", stdout);
cin >> n >> T >> k;
for (int i = 1; i <= n; i++) cin >> a[i]; // 从1号店到i号店需要的时间
for (int i = 1; i <= n; i++) cin >> b[i]; // 进入每个店内需要花费的时间
for (int i = 1; i <= n; i++) cin >> c[i]; // 每个店是不是喜欢的
for (int i = 1; i <= n; i++) { // 一次枚举每个店
if (c[i]) { // 如果当前店铺是我喜欢的
q1.push(b[i]); // q1里放入①我喜欢的②在优先队列中记录进入此店铺i中需要花费的时间
sum1 += b[i]; // sum1:记录进入所有k个以内店铺时需要的时间花费总和
if (q1.size() > k) { // 如果q1里面的个数已经达到k个那么就需要有某个店铺出队列
int x = q1.top(); // 因为是大顶堆,所以是堆顶元素出队列
q1.pop(); // 出队列
sum1 -= x; // 维护好sum1
q2.push(x); // 将q1中不是最优解的店移动到q2中去
sum2 += x; // 维护好q2中sum2的和
}
} else { // 如果当前店铺不是我喜欢的
q2.push(b[i]); // 直接放到q2里去
sum2 += b[i]; // 维护好q2中sum2的和
}
if (q1.size() < k) continue; // 如果还不够k个就继续考查下一个店铺
if (sum1 + a[i] > T) continue; // 如果当前的第i个店铺如果选择中就超出时间限制T,那没法选择i号店铺
int r = T - sum1 - a[i]; // 剩余的时间
// 不断交换q2中最大的 和 q3中最小的使得q2中都是代价小的q3中都是代价大的
while (q3.size() && q3.top() < q2.top()) {
int x = q2.top();
q2.pop();
q2.push(q3.top());
sum2 -= x;
sum2 += q3.top();
q3.pop();
q3.push(x);
}
// 剩余的时间不足以把q2中所有元素都访问到
while (q2.size() && r < sum2) {
int x = q2.top();
q3.push(x);
sum2 -= x;
q2.pop(); // 把q2中顶部最大的元素放到q3里去
}
while (q3.size() && r >= sum2 + q3.top()) {
int x = q3.top();
q2.push(x);
sum2 += x;
q3.pop();
}
// q.size()这个东东如果需要和int之类做加法必须加上强制转换
if (r >= sum2 && k + (int)q2.size() > res) res = k + (int)q2.size();
}
printf("%lld\n", res);
return 0;
}