#include <cstdio> #include <stack> #include <algorithm> using namespace std; static const int maxn = 500000; static int speed[maxn]; static long long int speed_sum[maxn + 1]; struct cut { long long int height; long long int day; int first_pos; }; static stack<cut> proc; int n, m; static inline void process_day(const long long int day, const long long int lvl) { long long int res = 0; struct cut tmp; int end = n; // take whole parts while (!proc.empty()) { tmp = proc.top(); if (tmp.height + ((long long) speed[tmp.first_pos]) * ((long long) (day - tmp.day)) < lvl) break; res += ((long long) (day - tmp.day)) * (speed_sum[tmp.first_pos] - speed_sum[end]); res += ((long long) (tmp.height - lvl)) * ((long long int) (end - tmp.first_pos)); end = tmp.first_pos; proc.pop(); } // locate new part begin int b1 = proc.empty() ? 0 : proc.top().first_pos; int b2 = end; const long long int base_level = proc.empty() ? 0 : proc.top().height; const long long int delta_t = proc.empty() ? day : (day - proc.top().day); while (b1 != b2) { const int c = (b1 + b2) / 2; if (((long long) speed[c]) * delta_t < lvl - base_level) b1 = c + 1; else b2 = c; } if (b2 == n) { printf("0\n"); return; } res += ((speed_sum[b1] - speed_sum[end])) * delta_t; res += ((base_level - lvl)) * ((long long int) (end - b1)); printf("%lld\n", res); // put new part tmp.first_pos = b1; tmp.day = day; tmp.height = lvl; proc.push(tmp); } int main() { scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &speed[i]); sort(speed, speed + n); // sums speed_sum[n - 1] = speed[n - 1]; speed_sum[n] = 0; for (int i = n - 2; i >= 0; i--) speed_sum[i] = speed_sum[i + 1] + (long long int) speed[i]; // process each day for (int i = 0; i < m; i++) { long long int day; long long int lvl; scanf("%lld %lld", &day, &lvl); process_day(day, lvl); } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include <cstdio> #include <stack> #include <algorithm> using namespace std; static const int maxn = 500000; static int speed[maxn]; static long long int speed_sum[maxn + 1]; struct cut { long long int height; long long int day; int first_pos; }; static stack<cut> proc; int n, m; static inline void process_day(const long long int day, const long long int lvl) { long long int res = 0; struct cut tmp; int end = n; // take whole parts while (!proc.empty()) { tmp = proc.top(); if (tmp.height + ((long long) speed[tmp.first_pos]) * ((long long) (day - tmp.day)) < lvl) break; res += ((long long) (day - tmp.day)) * (speed_sum[tmp.first_pos] - speed_sum[end]); res += ((long long) (tmp.height - lvl)) * ((long long int) (end - tmp.first_pos)); end = tmp.first_pos; proc.pop(); } // locate new part begin int b1 = proc.empty() ? 0 : proc.top().first_pos; int b2 = end; const long long int base_level = proc.empty() ? 0 : proc.top().height; const long long int delta_t = proc.empty() ? day : (day - proc.top().day); while (b1 != b2) { const int c = (b1 + b2) / 2; if (((long long) speed[c]) * delta_t < lvl - base_level) b1 = c + 1; else b2 = c; } if (b2 == n) { printf("0\n"); return; } res += ((speed_sum[b1] - speed_sum[end])) * delta_t; res += ((base_level - lvl)) * ((long long int) (end - b1)); printf("%lld\n", res); // put new part tmp.first_pos = b1; tmp.day = day; tmp.height = lvl; proc.push(tmp); } int main() { scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &speed[i]); sort(speed, speed + n); // sums speed_sum[n - 1] = speed[n - 1]; speed_sum[n] = 0; for (int i = n - 2; i >= 0; i--) speed_sum[i] = speed_sum[i + 1] + (long long int) speed[i]; // process each day for (int i = 0; i < m; i++) { long long int day; long long int lvl; scanf("%lld %lld", &day, &lvl); process_day(day, lvl); } return 0; } |