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