#include <iostream> #include <vector> #include <set> #include <algorithm> #include <cstdint> #include <queue> using namespace std; const long maxd = 1000000; class Piekarnik { public: int d; int nr; long long res; }; class Moment { public: Moment() { n = 1; prev = 0; next = 0; } long long t; long n; long next; long prev; }; int main() { int n, m; cin >> n >> m; vector<Moment> vt(n+2); vt[0].t = 0; for(int i = 1; i <= n; i++) cin >> vt[i].t; vt[n+1].t = 2000000000000000ll; for(int i = 0; i < vt.size(); i++) vt[i].next = i+1; vt.back().next = -1; for(int i = 0; i < vt.size(); i++) vt[i].prev = i-1; priority_queue< pair<long, long>, std::vector<pair<long, long> >, std::greater<pair<long, long> > > event_queue; long long czynnik = 0; long long licznik = 0; vector<Piekarnik> vp(m+1); vp[0].nr = 0; vp[0].d = 0; for(int i = 1; i <= m; i++) { vp[i].nr = i; cin >> vp[i].d; } sort(vp.begin()+1, vp.end(), [](const Piekarnik & a, const Piekarnik & b) -> bool { return a.d < b.d; } ); //sortuje rosnaco po d for(int i = 0; i < vt.size()-1; i++) { long long dist = vt[i+1].t - vt[i].t; if(dist <= maxd) event_queue.push( pair<long, long>(dist, i) ); } for(int id = 1; id <= m; id++) { int delta = vp[id].d - vp[id-1].d; licznik += czynnik * delta; //sklejenia while(!event_queue.empty() && event_queue.top().first <= vp[id].d) { auto r = event_queue.top(); event_queue.pop(); int idx = r.second; int idx2 = vt[idx].next; if(vt[idx].n == 0) continue; if(vt[idx].prev >= 0) vt[vt[idx].prev].next = vt[idx].next; vt[vt[idx].next].prev = vt[idx].prev; czynnik -= ((long long) vt[idx].n) * (vt[idx].n-1) / 2; czynnik -= ((long long) vt[idx2].n) * (vt[idx2].n-1) / 2; long long excess = vp[id].d * vt[idx].n - (vt[idx2].t - vt[idx].t); licznik += excess * vt[idx2].n; vt[idx2].n += vt[idx].n; vt[idx2].t = vt[idx].t; vt[idx].n = 0; czynnik += ((long long) vt[idx2].n) * (vt[idx2].n-1) / 2; if(vt[idx2].next > 0) { long long nextd = (vt[vt[idx2].next].t - vt[idx2].t + vt[idx2].n-1) / vt[idx2].n; if(nextd <= maxd) event_queue.push( pair<long, long>(nextd, idx2) ); } } vp[id].res = licznik; } sort(vp.begin()+1, vp.end(), [](const Piekarnik & a, const Piekarnik & b) -> bool { return a.nr < b.nr; } ); //sortuje rosnaco po nrd for(int i = 1; i < vp.size(); i++) cout << vp[i].res << endl; 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 126 127 128 | #include <iostream> #include <vector> #include <set> #include <algorithm> #include <cstdint> #include <queue> using namespace std; const long maxd = 1000000; class Piekarnik { public: int d; int nr; long long res; }; class Moment { public: Moment() { n = 1; prev = 0; next = 0; } long long t; long n; long next; long prev; }; int main() { int n, m; cin >> n >> m; vector<Moment> vt(n+2); vt[0].t = 0; for(int i = 1; i <= n; i++) cin >> vt[i].t; vt[n+1].t = 2000000000000000ll; for(int i = 0; i < vt.size(); i++) vt[i].next = i+1; vt.back().next = -1; for(int i = 0; i < vt.size(); i++) vt[i].prev = i-1; priority_queue< pair<long, long>, std::vector<pair<long, long> >, std::greater<pair<long, long> > > event_queue; long long czynnik = 0; long long licznik = 0; vector<Piekarnik> vp(m+1); vp[0].nr = 0; vp[0].d = 0; for(int i = 1; i <= m; i++) { vp[i].nr = i; cin >> vp[i].d; } sort(vp.begin()+1, vp.end(), [](const Piekarnik & a, const Piekarnik & b) -> bool { return a.d < b.d; } ); //sortuje rosnaco po d for(int i = 0; i < vt.size()-1; i++) { long long dist = vt[i+1].t - vt[i].t; if(dist <= maxd) event_queue.push( pair<long, long>(dist, i) ); } for(int id = 1; id <= m; id++) { int delta = vp[id].d - vp[id-1].d; licznik += czynnik * delta; //sklejenia while(!event_queue.empty() && event_queue.top().first <= vp[id].d) { auto r = event_queue.top(); event_queue.pop(); int idx = r.second; int idx2 = vt[idx].next; if(vt[idx].n == 0) continue; if(vt[idx].prev >= 0) vt[vt[idx].prev].next = vt[idx].next; vt[vt[idx].next].prev = vt[idx].prev; czynnik -= ((long long) vt[idx].n) * (vt[idx].n-1) / 2; czynnik -= ((long long) vt[idx2].n) * (vt[idx2].n-1) / 2; long long excess = vp[id].d * vt[idx].n - (vt[idx2].t - vt[idx].t); licznik += excess * vt[idx2].n; vt[idx2].n += vt[idx].n; vt[idx2].t = vt[idx].t; vt[idx].n = 0; czynnik += ((long long) vt[idx2].n) * (vt[idx2].n-1) / 2; if(vt[idx2].next > 0) { long long nextd = (vt[vt[idx2].next].t - vt[idx2].t + vt[idx2].n-1) / vt[idx2].n; if(nextd <= maxd) event_queue.push( pair<long, long>(nextd, idx2) ); } } vp[id].res = licznik; } sort(vp.begin()+1, vp.end(), [](const Piekarnik & a, const Piekarnik & b) -> bool { return a.nr < b.nr; } ); //sortuje rosnaco po nrd for(int i = 1; i < vp.size(); i++) cout << vp[i].res << endl; return 0; } |