#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
struct Node {
long long n = 0;
long long idxSum = 0;
};
const int MAX = 200200;
int n, m;
long long t[MAX];
int d[MAX];
std::map<int, long long> pRes;
std::map<long long, Node> groups;
std::map<long long, std::vector<std::pair<long long, long long> > > q;
int main(int argc, char *argv[]) {
scanf("%i%i", &n, &m);
t[0] = 0;
for (int c = 1; c <= n; c++) {
scanf("%lli", t + c);
}
for (int c = 0; c < m; c++) {
scanf("%i", d + c);
pRes[d[c]] = 0;
}
auto addJoin = [](long long tPrev, long long start) {
long long diff = start - tPrev;
long long join = (diff / groups[tPrev].n) + 1;
q[join].push_back(std::pair<long long, long long>(tPrev, start));
};
long long tPrev = -1;
for (int c = 0; c <= n; c++) {
long long start = t[c];
groups[start].n++;
//groups[start].tStart = start;
if (tPrev != -1 && tPrev != start) {
addJoin(tPrev, start);
}
tPrev = start;
}
long long nTotal = 0;
long long idxSumTotal = 0;
for (auto &sg : groups) {
nTotal += sg.second.n * (sg.second.n - 1) / 2;
}
for (auto iter = pRes.begin(); iter != pRes.end(); iter++) {
int pTime = iter->first;
while (!q.empty() && q.begin()->first <= pTime) {
long long tPrev = q.begin()->second.back().first;
long long start = q.begin()->second.back().second;
q.begin()->second.pop_back();
if (q.begin()->second.empty()) {
q.erase(q.begin());
}
if (groups.count(tPrev) > 0 && groups.count(start) > 0) {
auto &g1 = groups[tPrev];
auto &g2 = groups[start];
nTotal -= g1.n * (g1.n - 1) / 2;
nTotal -= g2.n * (g2.n - 1) / 2;
idxSumTotal -= g1.idxSum;
idxSumTotal -= g2.idxSum;
g1.n += g2.n;
g1.idxSum += (start - tPrev) * g2.n + g2.idxSum;
groups.erase(start);
nTotal += g1.n * (g1.n - 1) / 2;
idxSumTotal += g1.idxSum;
auto iNext = groups.lower_bound(tPrev);
if (++iNext != groups.end()) {
addJoin(tPrev, iNext->first);
}
}
}
pRes[pTime] = nTotal * pTime - idxSumTotal;
}
for (int c = 0; c < m; c++) {
printf("%lli\n", pRes[d[c]]);
}
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 | #include <cstdio> #include <algorithm> #include <map> #include <vector> struct Node { long long n = 0; long long idxSum = 0; }; const int MAX = 200200; int n, m; long long t[MAX]; int d[MAX]; std::map<int, long long> pRes; std::map<long long, Node> groups; std::map<long long, std::vector<std::pair<long long, long long> > > q; int main(int argc, char *argv[]) { scanf("%i%i", &n, &m); t[0] = 0; for (int c = 1; c <= n; c++) { scanf("%lli", t + c); } for (int c = 0; c < m; c++) { scanf("%i", d + c); pRes[d[c]] = 0; } auto addJoin = [](long long tPrev, long long start) { long long diff = start - tPrev; long long join = (diff / groups[tPrev].n) + 1; q[join].push_back(std::pair<long long, long long>(tPrev, start)); }; long long tPrev = -1; for (int c = 0; c <= n; c++) { long long start = t[c]; groups[start].n++; //groups[start].tStart = start; if (tPrev != -1 && tPrev != start) { addJoin(tPrev, start); } tPrev = start; } long long nTotal = 0; long long idxSumTotal = 0; for (auto &sg : groups) { nTotal += sg.second.n * (sg.second.n - 1) / 2; } for (auto iter = pRes.begin(); iter != pRes.end(); iter++) { int pTime = iter->first; while (!q.empty() && q.begin()->first <= pTime) { long long tPrev = q.begin()->second.back().first; long long start = q.begin()->second.back().second; q.begin()->second.pop_back(); if (q.begin()->second.empty()) { q.erase(q.begin()); } if (groups.count(tPrev) > 0 && groups.count(start) > 0) { auto &g1 = groups[tPrev]; auto &g2 = groups[start]; nTotal -= g1.n * (g1.n - 1) / 2; nTotal -= g2.n * (g2.n - 1) / 2; idxSumTotal -= g1.idxSum; idxSumTotal -= g2.idxSum; g1.n += g2.n; g1.idxSum += (start - tPrev) * g2.n + g2.idxSum; groups.erase(start); nTotal += g1.n * (g1.n - 1) / 2; idxSumTotal += g1.idxSum; auto iNext = groups.lower_bound(tPrev); if (++iNext != groups.end()) { addJoin(tPrev, iNext->first); } } } pRes[pTime] = nTotal * pTime - idxSumTotal; } for (int c = 0; c < m; c++) { printf("%lli\n", pRes[d[c]]); } return 0; } |
English