#include <iostream> #include <stdio.h> #include <string> #include <math.h> #include <set> #include <map> #include <unordered_map> using namespace std; #define ull unsigned long long #define ll long long class G { public: ll bt; ll count; ll sumT; ll d; G* next; G() {} void Set(G *n, ll dist) { sumT = 0; count = 1; d = dist; next = n; } }; struct comp { bool operator() (G* gl, G* gh) const { if (gl->d < gh->d) return true; if (gl->d == gh->d && gl < gh) return true; return false; } }; G timex[200001]; int main() { set<G*, comp> gr; set<ll> cookTimes; set<ll>::iterator cookIter; unordered_map<ll, ll> sol; int n = 0; int m = 0; scanf("%i %i", &n, &m); timex[0].bt = 0; for (ll i = 1; i <= n; ++i) { scanf("%lld", &(timex[i].bt)); } ll *owen = new ll[m]; for (ll i = 0; i < m; ++i) { scanf("%lld", &owen[i]); cookTimes.insert(owen[i]); } timex[n].Set(NULL, 1000000000000); gr.insert(&timex[n]); for (ll i = n - 1; i >= 0; --i) { timex[i].Set(&timex[i + 1], timex[i + 1].bt - timex[i].bt); gr.insert(&timex[i]); } G *g1, *g2; ll cookMulti = 0; ll timeCount = 0; ll cookTime = 0; while (!cookTimes.empty()) { cookIter = cookTimes.begin(); cookTime = (*cookIter); while ((*gr.begin())->d < cookTime) { g1 = (*gr.begin()); g2 = g1->next; cookMulti -= (g1->count * (g1->count - 1)) / 2; cookMulti -= (g2->count * (g2->count - 1)) / 2; timeCount -= g1->sumT; timeCount -= g2->sumT; g1->count += g2->count; g1->sumT += g2->sumT + g2->count * (g2->bt - g1->bt); if (g2->next != NULL) g1->d = (g2->next->bt - g1->bt) / g1->count; else g1->d = g2->d; g1->next = g2->next; cookMulti += (g1->count * (g1->count - 1)) / 2; timeCount += g1->sumT; gr.erase(gr.begin()); gr.erase(g2); gr.insert(g1); } sol[cookTime] = cookMulti * cookTime - timeCount; cookTimes.erase(cookIter); } for (ll i = 0; i < m; ++i) { printf("%lld\n", sol[owen[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 121 122 123 124 125 | #include <iostream> #include <stdio.h> #include <string> #include <math.h> #include <set> #include <map> #include <unordered_map> using namespace std; #define ull unsigned long long #define ll long long class G { public: ll bt; ll count; ll sumT; ll d; G* next; G() {} void Set(G *n, ll dist) { sumT = 0; count = 1; d = dist; next = n; } }; struct comp { bool operator() (G* gl, G* gh) const { if (gl->d < gh->d) return true; if (gl->d == gh->d && gl < gh) return true; return false; } }; G timex[200001]; int main() { set<G*, comp> gr; set<ll> cookTimes; set<ll>::iterator cookIter; unordered_map<ll, ll> sol; int n = 0; int m = 0; scanf("%i %i", &n, &m); timex[0].bt = 0; for (ll i = 1; i <= n; ++i) { scanf("%lld", &(timex[i].bt)); } ll *owen = new ll[m]; for (ll i = 0; i < m; ++i) { scanf("%lld", &owen[i]); cookTimes.insert(owen[i]); } timex[n].Set(NULL, 1000000000000); gr.insert(&timex[n]); for (ll i = n - 1; i >= 0; --i) { timex[i].Set(&timex[i + 1], timex[i + 1].bt - timex[i].bt); gr.insert(&timex[i]); } G *g1, *g2; ll cookMulti = 0; ll timeCount = 0; ll cookTime = 0; while (!cookTimes.empty()) { cookIter = cookTimes.begin(); cookTime = (*cookIter); while ((*gr.begin())->d < cookTime) { g1 = (*gr.begin()); g2 = g1->next; cookMulti -= (g1->count * (g1->count - 1)) / 2; cookMulti -= (g2->count * (g2->count - 1)) / 2; timeCount -= g1->sumT; timeCount -= g2->sumT; g1->count += g2->count; g1->sumT += g2->sumT + g2->count * (g2->bt - g1->bt); if (g2->next != NULL) g1->d = (g2->next->bt - g1->bt) / g1->count; else g1->d = g2->d; g1->next = g2->next; cookMulti += (g1->count * (g1->count - 1)) / 2; timeCount += g1->sumT; gr.erase(gr.begin()); gr.erase(g2); gr.insert(g1); } sol[cookTime] = cookMulti * cookTime - timeCount; cookTimes.erase(cookIter); } for (ll i = 0; i < m; ++i) { printf("%lld\n", sol[owen[i]]); } return 0; } |