It’s another Startup, and that means there are T-shirts to order. In order to make sure T-shirts are shipped as soon as possible, we’ve decided that this year we’re going to order all of the necessary T-shirts before the actual competition. The top C contestants are going to be awarded T-shirts, but we obviously don’t know which contestants that will be. The plan is to get the T-Shirt sizes of all contestants before the actual competition, and then order enough T-shirts so that no matter who is in the top C we’ll have T-shirts available in order to award them.
In order to get the T-shirt sizes of the contestants, we will send out a survey. The survey will allow contestants to either specify a single desired T-shirt size, or two adjacent T-shirt sizes. If a contestant specifies two sizes, it means that they can be awarded either size.
As you can probably tell, this plan could require ordering a lot of unnecessary T-shirts. We’d like your help to determine the minimum number of T-shirts we’ll need to order to ensure that we’ll be able to award T-shirts no matter the outcome of the competition.
Input
Input will begin with two integers N and C (1 ≤ N ≤ 2·105, 1 ≤ C), the number of T-shirt sizes and number of T-shirts to be awarded, respectively.
Following this is a line with 2·N - 1 integers, s 1 through s 2·N - 1 (0 ≤ s i ≤ 108). For odd i, s i indicates the number of contestants desiring T-shirt size ((i + 1) / 2). For even i, s i indicates the number of contestants okay receiving either of T-shirt sizes (i / 2) and (i / 2 + 1). C will not exceed the total number of contestants.
Output
Print the minimum number of T-shirts we need to buy.
Examples
input
2 200
100 250 100
output
200
input
4 160
88 69 62 29 58 52 44
output
314
Note
In the first example, we can buy 100 of each size.
Solution:
#include <bits/stdc++.h> using namespace std; const int N = 1234567; const long long inf = (long long) 1e18; long long ma[N], ml[N], mr[N]; int a[N]; long long s[N], f[N]; void modify(int q, long long v) { ma[q] = max(ma[q], v); int x = q; while (x < N) { ml[x] = max(ml[x], v); x |= (x + 1); } x = q; while (x >= 0) { mr[x] = max(mr[x], v); x = (x & (x + 1)) - 1; } } long long get(int ll, int rr) { long long v = -inf; int x = ll; while ((x | (x + 1)) <= rr) { v = max(v, mr[x]); x |= (x + 1); } v = max(v, ma[x]); x = rr; while ((x & (x + 1)) - 1 >= ll) { v = max(v, ml[x]); x = (x & (x + 1)) - 1; } return v; } int main() { int n; long long c; cin >> n >> c; for (int i = 0; i < 2 * n - 1; i++) { scanf("%d", a + i); } s[0] = 0; for (int i = 0; i < 2 * n - 1; i++) { s[i + 1] = s[i] + a[i]; } for (int i = 0; i < N; i++) { ma[i] = ml[i] = mr[i] = -inf; } f[0] = 0; modify(0, 0); for (int i = 1; i <= n; i++) { int low = 0, high = i; while (low < high) { int mid = (low + high) >> 1; if (s[2 * i - 1] - s[2 * mid] < c) { high = mid; } else { low = mid + 1; } } f[i] = -inf; if (low > 0) { f[i] = max(f[i], c + f[low - 1]); } if (low < i) { f[i] = max(f[i], s[2 * i - 1] + get(low, i - 1)); } modify(i, f[i] - s[2 * i]); } cout << f[n] << endl; return 0; }