#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; } |
English