#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const long long kMaxD = 1000000;
// const long long kMaxD = 1;
struct Block {
bool active;
long long count;
int next;
long long width;
};
int main() {
int n;
int m;
scanf("%d%d", &n, &m);
vector<long long> t(n + 1);
for (int i = 1; i <= n; ++i) scanf("%lld", &t[i]);
vector<Block> b(n);
for (int i = 0; i < n; ++i) {
b[i].active = true;
b[i].count = 1;
b[i].next = i + 1;
b[i].width = t[i + 1] - t[i];
}
b[n - 1].next = -1;
vector<long long> ret(kMaxD + 1);
vector<int> q(kMaxD + 1, -1);
vector<int> next(n, -1);
for (int i = 0; i < n; ++i) {
long long last = min(kMaxD, b[i].width / b[i].count);
// cerr << i << ' ' << last << endl;
next[i] = q[last];
q[last] = i;
}
long long A = 0;
long long B = 0;
for (int i = 0; i <= kMaxD; ++i) {
ret[i] = A * i + B;
// cerr << i << ' ' << ret[i] << endl;
if (i == kMaxD) break;
while (q[i] != -1) {
int j = q[i];
q[i] = next[j];
if (!b[j].active) continue;
// cerr << "Merging block " << j << endl;
int j_next = b[j].next;
if (j_next == -1) {
B += (i + 1) * b[j].count - b[j].width;
// cerr << "B " << B << endl;
b[j].width = (i + 1) * b[j].count;
next[j] = q[i + 1];
q[i + 1] = j;
// cerr << "Reinserting " << b[j].width << "/" << b[j].count << " at " << i + 1 << endl;
} else {
A += b[j].count * b[j_next].count;
// cerr << "A " << A << endl;
B -= b[j].count * b[j_next].count * i;
B -= (b[j].width - i * b[j].count) * b[j_next].count;
// cerr << "B " << B << endl;
b[j].width += b[j_next].width;
b[j].count += b[j_next].count;
b[j_next].active = false;
int j_next_next = b[j_next].next;
b[j].next = j_next_next;
long long last = min(kMaxD, b[j].width / b[j].count);
// cerr << "Reinserting " << b[j].width << "/" << b[j].count << " at " << last << endl;
next[j] = q[last];
q[last] = j;
}
}
}
while (m--) {
int d;
scanf("%d", &d);
printf("%lld\n", ret[d]);
}
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 | #include <algorithm> #include <cstdio> #include <iostream> #include <queue> #include <vector> using namespace std; const long long kMaxD = 1000000; // const long long kMaxD = 1; struct Block { bool active; long long count; int next; long long width; }; int main() { int n; int m; scanf("%d%d", &n, &m); vector<long long> t(n + 1); for (int i = 1; i <= n; ++i) scanf("%lld", &t[i]); vector<Block> b(n); for (int i = 0; i < n; ++i) { b[i].active = true; b[i].count = 1; b[i].next = i + 1; b[i].width = t[i + 1] - t[i]; } b[n - 1].next = -1; vector<long long> ret(kMaxD + 1); vector<int> q(kMaxD + 1, -1); vector<int> next(n, -1); for (int i = 0; i < n; ++i) { long long last = min(kMaxD, b[i].width / b[i].count); // cerr << i << ' ' << last << endl; next[i] = q[last]; q[last] = i; } long long A = 0; long long B = 0; for (int i = 0; i <= kMaxD; ++i) { ret[i] = A * i + B; // cerr << i << ' ' << ret[i] << endl; if (i == kMaxD) break; while (q[i] != -1) { int j = q[i]; q[i] = next[j]; if (!b[j].active) continue; // cerr << "Merging block " << j << endl; int j_next = b[j].next; if (j_next == -1) { B += (i + 1) * b[j].count - b[j].width; // cerr << "B " << B << endl; b[j].width = (i + 1) * b[j].count; next[j] = q[i + 1]; q[i + 1] = j; // cerr << "Reinserting " << b[j].width << "/" << b[j].count << " at " << i + 1 << endl; } else { A += b[j].count * b[j_next].count; // cerr << "A " << A << endl; B -= b[j].count * b[j_next].count * i; B -= (b[j].width - i * b[j].count) * b[j_next].count; // cerr << "B " << B << endl; b[j].width += b[j_next].width; b[j].count += b[j_next].count; b[j_next].active = false; int j_next_next = b[j_next].next; b[j].next = j_next_next; long long last = min(kMaxD, b[j].width / b[j].count); // cerr << "Reinserting " << b[j].width << "/" << b[j].count << " at " << last << endl; next[j] = q[last]; q[last] = j; } } } while (m--) { int d; scanf("%d", &d); printf("%lld\n", ret[d]); } return 0; } |
English