#include <cstdio>
#include <utility>
#include <queue>
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define FORD(i, a, b) for (int i = (a); i >= (b); --i)
#define PLLII pair<long long, pair<int, int>>
#define MP(a, b, c) make_pair(a, make_pair(b, c))
#define LL long long
using namespace std;
const int maxn = 200010;
const int maxd = 1000010;
const LL maxt = 1000000000010L;
int n, m;
LL diff[maxn];
int d[maxn];
int topd;
priority_queue<PLLII, vector<PLLII>, greater<PLLII>> q;
int nexti[maxn];
int previ[maxn];
LL left[maxn];
LL right[maxn];
LL rightsum;
LL nextsum;
int last[maxn];
int time[maxn];
LL gnow[maxn];
LL g[maxn];
LL res[maxd];
LL powright(int right) {
return ((LL)right*((LL)right + 1))/2;
}
int main() {
scanf("%d%d", &n, &m);
LL prevt = 0;
LL currt;
REP(i, n) {
scanf("%lld", &currt);
diff[i] = currt - prevt;
prevt = currt;
q.push(MP(diff[i], i, -1));
left[i] = 1;
nexti[i] = i + 1;
previ[i] = i - 1;
time[i] = -1;
}
diff[n] = 2L*maxn*maxd;
REP(i, m) {
scanf("%d", &d[i]);
if (d[i] > topd) {
topd = d[i];
}
}
LL result = 0;
int i;
int timei;
LL bonus;
LL sum = 0;
FOR(now, 0, topd) {
result += sum;
sum = rightsum;
nextsum = rightsum;
res[now] = result;
// printf("NOW %d result %lld\n", now, result);
while (q.top().first == (LL)now) {
int first = q.top().first;
i = q.top().second.first;
timei = q.top().second.second;
q.pop();
if (timei < time[i]) {
continue;
}
// printf("PROCESSING %lld i %d last %d (left %d, right %d) prev %d next %d\n", first, i, timei, left[i], right[i], previ[i], nexti[i]);
diff[i] -= (left[i] + right[i])*(now - last[i]);
// printf("diff[i] %lld\n", diff[i]);
last[i] = now;
diff[nexti[i]] -= (left[nexti[i]] + right[nexti[i]])*(now - last[nexti[i]]);
// printf("diff[next[i]] %lld\n", diff[nexti[i]]);
last[nexti[i]] = now;
nextsum -= (gnow[i] == now) ? powright(g[i]) : powright(right[i]);
rightsum -= powright(right[i]);
nextsum -= powright(right[nexti[i]]);
rightsum -= powright(right[nexti[i]]);
// printf("BEFOR r[i] %d r[n[i]] %d\n", right[i], right[nexti[i]]);
right[nexti[i]] += left[i] + right[i];
// printf("r[i] %d r[n[i]] %d\n", right[i], right[nexti[i]]);
bonus = diff[i];
// printf("bonus %lld\n", bonus);
nextsum += powright(bonus) + powright((gnow[i] == now) ? right[nexti[i]] - right[i] + g[i] - bonus : right[nexti[i]] - bonus);
rightsum += powright(right[nexti[i]]);
g[nexti[i]] = right[nexti[i]] - bonus;
gnow[nexti[i]] = now;
// Adjust pointers to skip the current block.
if (previ[i] >= 0) {
nexti[previ[i]] = nexti[i];
}
previ[nexti[i]] = previ[i];
// Schedule next check.
time[nexti[i]] = now;
q.push(MP((LL)now + diff[nexti[i]]/(left[nexti[i]] + right[nexti[i]]), nexti[i], now));
// printf("rightsum temp %lld\n", rightsum);
sum = nextsum;
}
// printf("RIGHTSUM %lld\n", rightsum);
}
REP(i, m) {
printf("%lld\n", res[d[i]]);
}
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 116 117 118 | #include <cstdio> #include <utility> #include <queue> #define REP(i, n) for (int i = 0; i < (n); ++i) #define FOR(i, a, b) for (int i = (a); i <= (b); ++i) #define FORD(i, a, b) for (int i = (a); i >= (b); --i) #define PLLII pair<long long, pair<int, int>> #define MP(a, b, c) make_pair(a, make_pair(b, c)) #define LL long long using namespace std; const int maxn = 200010; const int maxd = 1000010; const LL maxt = 1000000000010L; int n, m; LL diff[maxn]; int d[maxn]; int topd; priority_queue<PLLII, vector<PLLII>, greater<PLLII>> q; int nexti[maxn]; int previ[maxn]; LL left[maxn]; LL right[maxn]; LL rightsum; LL nextsum; int last[maxn]; int time[maxn]; LL gnow[maxn]; LL g[maxn]; LL res[maxd]; LL powright(int right) { return ((LL)right*((LL)right + 1))/2; } int main() { scanf("%d%d", &n, &m); LL prevt = 0; LL currt; REP(i, n) { scanf("%lld", &currt); diff[i] = currt - prevt; prevt = currt; q.push(MP(diff[i], i, -1)); left[i] = 1; nexti[i] = i + 1; previ[i] = i - 1; time[i] = -1; } diff[n] = 2L*maxn*maxd; REP(i, m) { scanf("%d", &d[i]); if (d[i] > topd) { topd = d[i]; } } LL result = 0; int i; int timei; LL bonus; LL sum = 0; FOR(now, 0, topd) { result += sum; sum = rightsum; nextsum = rightsum; res[now] = result; // printf("NOW %d result %lld\n", now, result); while (q.top().first == (LL)now) { int first = q.top().first; i = q.top().second.first; timei = q.top().second.second; q.pop(); if (timei < time[i]) { continue; } // printf("PROCESSING %lld i %d last %d (left %d, right %d) prev %d next %d\n", first, i, timei, left[i], right[i], previ[i], nexti[i]); diff[i] -= (left[i] + right[i])*(now - last[i]); // printf("diff[i] %lld\n", diff[i]); last[i] = now; diff[nexti[i]] -= (left[nexti[i]] + right[nexti[i]])*(now - last[nexti[i]]); // printf("diff[next[i]] %lld\n", diff[nexti[i]]); last[nexti[i]] = now; nextsum -= (gnow[i] == now) ? powright(g[i]) : powright(right[i]); rightsum -= powright(right[i]); nextsum -= powright(right[nexti[i]]); rightsum -= powright(right[nexti[i]]); // printf("BEFOR r[i] %d r[n[i]] %d\n", right[i], right[nexti[i]]); right[nexti[i]] += left[i] + right[i]; // printf("r[i] %d r[n[i]] %d\n", right[i], right[nexti[i]]); bonus = diff[i]; // printf("bonus %lld\n", bonus); nextsum += powright(bonus) + powright((gnow[i] == now) ? right[nexti[i]] - right[i] + g[i] - bonus : right[nexti[i]] - bonus); rightsum += powright(right[nexti[i]]); g[nexti[i]] = right[nexti[i]] - bonus; gnow[nexti[i]] = now; // Adjust pointers to skip the current block. if (previ[i] >= 0) { nexti[previ[i]] = nexti[i]; } previ[nexti[i]] = previ[i]; // Schedule next check. time[nexti[i]] = now; q.push(MP((LL)now + diff[nexti[i]]/(left[nexti[i]] + right[nexti[i]]), nexti[i], now)); // printf("rightsum temp %lld\n", rightsum); sum = nextsum; } // printf("RIGHTSUM %lld\n", rightsum); } REP(i, m) { printf("%lld\n", res[d[i]]); } return 0; } |
English