#include #include #include #include #define MAXN 1000000 using namespace std; int a[MAXN]; int b[MAXN]; struct SET_QUAD { int c[MAXN][2]; // voda, cena int n; SET_QUAD(): n(0) {} void insert(int a, int b) { c[n][0] = a; c[n][1] = b; n++; } void increase(int d) { for (int i = 0; i < n; i++) c[i][0] += d; } int best() { int max = -1; for (int i = 0; i < n; i++) { if (c[i][0] >= 0 && c[i][1] > max) max = c[i][1]; } return max; } void write() { for (int i = 0; i < n; i++) printf("(%d, %d) ", c[i][0], c[i][1]); printf("\n"); } }; struct SET_LINLOG { typedef set > S; // voda, cena typedef S::const_iterator IT; S s; int diff; SET_LINLOG(): diff(0) {} void insert(int a, int b) { IT it = s.insert(make_pair(a - diff, b)).first, it2; while (1) { // Smažeme zbytečné páry, množinu udržujeme uspořádanou podle cen. if (it != s.begin() && (it2 = it, it->second >= (--it2)->second)) { // *it je lokálně lepší než *(it - 1) s.erase(it2); continue; } if (it2 = it, (++it2 != s.end()) && (it2->second >= it->second)) { // *(it + 1) je lokálně lepší než *it s.erase(it); it = it2; continue; } break; } } void increase(int d) { diff += d; } int best() { IT it = s.lower_bound(make_pair(-diff, 0)); if (it == s.end()) return -1; return it->second; } void write() { for(IT it = s.begin(); it != s.end(); it++) printf("(%d, %d) ", it->first + diff, it->second); printf("\n"); } }; SET_LINLOG Set; int main() { int n, best, price_sum = 0; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", a + i); if (i != n - 1) { scanf("%d", b + i); price_sum += b[i]; } } Set.insert(0, 0); for (int i = 0; i < n; i++) { Set.increase(a[i]); if(i == n - 1) { // Jsme na konci printf("%d\n", price_sum - Set.best()); } else if ((best = Set.best()) >= 0) { // Můžeme provést řez (levá část bude OK) Set.insert(0, best + b[i]); } } return 0; }