#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define N 500007
long long int vel[N];
long long int sum[N] = {0};
int n;
struct pref {
int end; /* last affected piece */
long long int t;/* time of cut */
long long int h;/* height of cut */
} Q[N];
int top;
struct pref base_cut;
long long int height(long long int t, struct pref *p)
{
return p->h + (t - p->t) * vel[p->end];
}
long long int cut(long long int d, long long int b)
{
int s = 0, e, c;
long long int res = 0, prev = -1, su, part;
struct pref *last;
while (top && height(d, &Q[top]) > b) {
assert(d >= Q[top].t);
assert(Q[top].end >= prev);
if (prev >= 0)
su = sum[prev];
else
su = 0;
assert(sum[Q[top].end] >= su);
part = (d - Q[top].t) * (sum[Q[top].end] - su) +
(Q[top].h - b) * (Q[top].end - prev);
if (part > 0)
res += part;
assert(res >= 0);
prev = Q[top].end;
s = Q[top--].end;
}
last = top ? &Q[top] : &base_cut;
e = last->end;
++top;
Q[top].t = d;
Q[top].h = b;
c = (e + s)/2;
while (e - s > 1) {
c = (e + s)/2;
if (last->h + (d - last->t) * vel[c] > b)
s = c;
else
e = c;
}
Q[top].end = e;
assert(d >= last->t);
assert(e >= prev);
if (prev >= 0)
su = sum[prev];
else
su = 0;
assert(sum[e] >= su);
part = (d - last->t) * (sum[e] - su) +
(last->h - b) * (e - prev);
if (part > 0)
res += part;
return res;
}
static int cmp(const void *p1, const void *p2)
{
return *(const long long int *)p2 - *(const long long int *)p1;
}
int main()
{
int m, i;
long long int d, b;
scanf("%d%d", &n, &m);
for (i = 0; i < n; ++i) {
scanf("%lld", &vel[i]);
}
qsort(vel, n, sizeof(long long int), cmp);
base_cut.end = n-1;
base_cut.t = 0;
base_cut.h = 0;
sum[0] = vel[0];
for (i = 1; i < n; ++i)
sum[i] = sum[i - 1] + vel[i];
top = 0;
for (i = 0; i < m; ++i) {
scanf("%lld%lld", &d, &b);
printf("%lld\n", cut(d, b));
}
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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | #include <stdio.h> #include <stdlib.h> #include <assert.h> #define N 500007 long long int vel[N]; long long int sum[N] = {0}; int n; struct pref { int end; /* last affected piece */ long long int t;/* time of cut */ long long int h;/* height of cut */ } Q[N]; int top; struct pref base_cut; long long int height(long long int t, struct pref *p) { return p->h + (t - p->t) * vel[p->end]; } long long int cut(long long int d, long long int b) { int s = 0, e, c; long long int res = 0, prev = -1, su, part; struct pref *last; while (top && height(d, &Q[top]) > b) { assert(d >= Q[top].t); assert(Q[top].end >= prev); if (prev >= 0) su = sum[prev]; else su = 0; assert(sum[Q[top].end] >= su); part = (d - Q[top].t) * (sum[Q[top].end] - su) + (Q[top].h - b) * (Q[top].end - prev); if (part > 0) res += part; assert(res >= 0); prev = Q[top].end; s = Q[top--].end; } last = top ? &Q[top] : &base_cut; e = last->end; ++top; Q[top].t = d; Q[top].h = b; c = (e + s)/2; while (e - s > 1) { c = (e + s)/2; if (last->h + (d - last->t) * vel[c] > b) s = c; else e = c; } Q[top].end = e; assert(d >= last->t); assert(e >= prev); if (prev >= 0) su = sum[prev]; else su = 0; assert(sum[e] >= su); part = (d - last->t) * (sum[e] - su) + (last->h - b) * (e - prev); if (part > 0) res += part; return res; } static int cmp(const void *p1, const void *p2) { return *(const long long int *)p2 - *(const long long int *)p1; } int main() { int m, i; long long int d, b; scanf("%d%d", &n, &m); for (i = 0; i < n; ++i) { scanf("%lld", &vel[i]); } qsort(vel, n, sizeof(long long int), cmp); base_cut.end = n-1; base_cut.t = 0; base_cut.h = 0; sum[0] = vel[0]; for (i = 1; i < n; ++i) sum[i] = sum[i - 1] + vel[i]; top = 0; for (i = 0; i < m; ++i) { scanf("%lld%lld", &d, &b); printf("%lld\n", cut(d, b)); } return 0; } |
English