Wed, 30 Jan 2019 17:23:36 GMT

master
大蒟蒻 7 years ago
parent a4f56bda64
commit caebc2d7b9

@ -39,3 +39,13 @@ multiset.upper_bound()
### J - 区间交
说实话,没怎么看懂题解。望大佬们不吝告知。
### K - Music in Car
[正版题解](http://codeforces.com/blog/entry/49160)
> This problem can be solved with help of two pointers. We will store two sets — set with songs with full time and set with songs with partly time. How to move left and right pointers and recalculate current answer? Let left end of the current segment is*l*and right end of the segment is*r*. Let the set of songs with partly time is*half*and with full time —*full*. In this sets we will store pairs — time of listening each song and it number.
>
> Right end we will move in the following way: if we can add partly song and we have enough time to listen it — we take it (also add this song to*half*) and add to time$(t_r+1)/2$and add to the answer$a_r$. In the other case we have two cases. First — we add current song as full song, second — we add current song as partly song. Here we need to choose case with less with the total time. Also here we need to correctly add song to sets and update total time and the answer. If total time became more than*k*we are not allowed to move*r*. Now we need to update global answer with the current value of answer.
>
> Left end we will move in the following way: if we took song as full song we delete it from*full*, subtract from total time length of this song. In the other case we delete it from*half*and subtract from the total time the$(t_r+1)/2$. After that we try to take some song from*full*. If the size of*full*is 0, we can not do that. If we done it we need to change total time on the songs on the current segment.

@ -2,7 +2,47 @@
#define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 50;
int a[N], t[N];
#define hlf(x) (((x) + 1) >> 1)
int main()
{
int n, w, k;
scanf("%d%d%d", &n, &w, &k);
for (int i = 0; i < n; i++) scanf("%d", a + i);
for (int i = 0; i < n; i++) scanf("%d", t + i);
multiset<int> s1, s2;
int tsum = 0, hsum = 0, ans = 0;
for (int l = 0, r = 0; r < n; r++)
{
s1.insert(t[r]);
tsum += hlf(t[r]);
hsum += a[r];
if (s1.size() > w)
{
int x = *s1.begin();
s2.insert(x);
tsum += x - hlf(x);
s1.erase(s1.begin());
}
for (; l <= r && tsum > k; hsum -= a[l++])
if (t[l] < *s1.begin())
s2.erase(s2.find(t[l])), tsum -= t[l];
else
{
s1.erase(s1.find(t[l]));
tsum -= hlf(t[l]);
if (!s2.empty())
{
auto x = s2.end();
--x;
tsum += hlf(*x) - *x;
s1.insert(*x);
s2.erase(x);
}
}
ans = max(ans, hsum);
}
printf("%d", ans);
return 0;
}

Loading…
Cancel
Save