#include <cstdio> #include <list> #include <map> #include <queue> #define MAXN 200004 #define INF 1000000000000000000ll #define lld long long int using namespace std; int n, m; lld t[MAXN]; int d[MAXN]; struct event { int num; lld count; lld start; lld cDelay; event(int num, lld count, lld start, lld cDelay) { this->num = num; this->count = count; this->start = start; this->cDelay = cDelay; } }; list <event> ev; struct heapEntry { int num; lld time; list<event>::iterator it; heapEntry(int num, lld time, list<event>::iterator it) { this->num = num; this->time = time; this->it = it; } }; bool operator < (const heapEntry &m1, const heapEntry &m2) { return m1.time > m2.time; } priority_queue<heapEntry> pq; map<int, lld> results; lld sumDelay; lld sumNNm1p2; char exists[MAXN]; // if so the group is still valid int main() { scanf("%d%d", &n, &m); ev.push_back(event(0, 1, 0, 0)); auto pt = ev.begin(); exists[0] = 1; int last = 0; for (int i = 1; i <= n; i++) { scanf("%lld", &t[i]); if (t[i] == t[i - 1]) { pt->count++; } else { lld joinTime = (t[i] - pt->start + pt->count - 1) / pt->count; pq.push(heapEntry(last, joinTime, pt)); sumNNm1p2 += (pt->count) * (pt->count - 1) / 2; last = i; ev.push_back(event(i, 1, t[i], 0)); pt++; exists[i] = 1; } } pq.push(heapEntry(last, INF, pt)); sumNNm1p2 += (pt->count) * (pt->count - 1) / 2; for (int i = 0; i < m; i++) { scanf("%d", &d[i]); results[d[i]] = 0ll; } for (auto &e : results) { // printf("%d:\n", e.first); while (pq.top().time <= e.first) { heapEntry ent = pq.top(); pq.pop(); if (!exists[ent.num]) continue; //printf("(%lld %lld\n", ent.time, ent.num); auto it1 = ent.it, it2 = ent.it; it2++; if (it2 != ev.end()) { exists[it2->num] = 0; sumNNm1p2 -= ((it1->count) * (it1->count - 1) + (it2->count) * (it2->count - 1)) / 2; it1->count = it1->count + it2->count; sumNNm1p2 += (it1->count) * (it1->count - 1) / 2; sumDelay += (it2->start - it1->start) * it2->count; it1->cDelay = it1->cDelay + it2->cDelay + (it2->start - it1->start) * it2->count; it2++; if (it2 != ev.end()) { lld joinTime = (it2->start - it1->start + it1->count - 1) / it1->count; pq.push(heapEntry(it1->num, joinTime, it1)); } ev.erase(++it1); } } e.second = e.first * sumNNm1p2 - sumDelay; } for (int i = 0; i < m; i++) { printf("%lld\n", results[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 119 120 | #include <cstdio> #include <list> #include <map> #include <queue> #define MAXN 200004 #define INF 1000000000000000000ll #define lld long long int using namespace std; int n, m; lld t[MAXN]; int d[MAXN]; struct event { int num; lld count; lld start; lld cDelay; event(int num, lld count, lld start, lld cDelay) { this->num = num; this->count = count; this->start = start; this->cDelay = cDelay; } }; list <event> ev; struct heapEntry { int num; lld time; list<event>::iterator it; heapEntry(int num, lld time, list<event>::iterator it) { this->num = num; this->time = time; this->it = it; } }; bool operator < (const heapEntry &m1, const heapEntry &m2) { return m1.time > m2.time; } priority_queue<heapEntry> pq; map<int, lld> results; lld sumDelay; lld sumNNm1p2; char exists[MAXN]; // if so the group is still valid int main() { scanf("%d%d", &n, &m); ev.push_back(event(0, 1, 0, 0)); auto pt = ev.begin(); exists[0] = 1; int last = 0; for (int i = 1; i <= n; i++) { scanf("%lld", &t[i]); if (t[i] == t[i - 1]) { pt->count++; } else { lld joinTime = (t[i] - pt->start + pt->count - 1) / pt->count; pq.push(heapEntry(last, joinTime, pt)); sumNNm1p2 += (pt->count) * (pt->count - 1) / 2; last = i; ev.push_back(event(i, 1, t[i], 0)); pt++; exists[i] = 1; } } pq.push(heapEntry(last, INF, pt)); sumNNm1p2 += (pt->count) * (pt->count - 1) / 2; for (int i = 0; i < m; i++) { scanf("%d", &d[i]); results[d[i]] = 0ll; } for (auto &e : results) { // printf("%d:\n", e.first); while (pq.top().time <= e.first) { heapEntry ent = pq.top(); pq.pop(); if (!exists[ent.num]) continue; //printf("(%lld %lld\n", ent.time, ent.num); auto it1 = ent.it, it2 = ent.it; it2++; if (it2 != ev.end()) { exists[it2->num] = 0; sumNNm1p2 -= ((it1->count) * (it1->count - 1) + (it2->count) * (it2->count - 1)) / 2; it1->count = it1->count + it2->count; sumNNm1p2 += (it1->count) * (it1->count - 1) / 2; sumDelay += (it2->start - it1->start) * it2->count; it1->cDelay = it1->cDelay + it2->cDelay + (it2->start - it1->start) * it2->count; it2++; if (it2 != ev.end()) { lld joinTime = (it2->start - it1->start + it1->count - 1) / it1->count; pq.push(heapEntry(it1->num, joinTime, it1)); } ev.erase(++it1); } } e.second = e.first * sumNNm1p2 - sumDelay; } for (int i = 0; i < m; i++) { printf("%lld\n", results[d[i]]); } return 0; } |