#include <iostream> #include <algorithm> #include <vector> #include <queue> #include <functional> #include <utility> #include <tuple> using namespace std; struct pointInTime { long long int time; int guest_count; int prev_point; inline bool operator <(const pointInTime &p2) const { return time < p2.time; } }; struct oven { int bTime; int id; inline bool operator <(const oven &p2) const { return bTime < p2.bTime; } }; struct Event { int minZ; int idd; bool start; public: bool operator< (const Event &p2) const { return minZ > p2.minZ; } }; typedef priority_queue<Event> qType ; void initialize(vector<pointInTime> t, qType &q) { for (int i = 1; i < (int)t.size(); ++i) { q.push({ (int)(t[i].time - t[i-1].time) / t[i-1].guest_count + (((t[i].time - t[i - 1].time) % (t[i - 1].guest_count)) ? 1:0), i, true }); } } void querry(qType &q, long long &curT, long long &AllT, long long int nextT, int &partial, vector<pointInTime> t) { Event e = q.top(); q.pop(); AllT += partial * (e.minZ - curT); curT = e.minZ; if (e.start) { if (t[e.idd].prev_point == -1) return; pointInTime& poprzedni = t[t[e.idd].prev_point]; if (e.idd + 1 < (int)t.size()) t[e.idd + 1].prev_point = t[t[e.idd].prev_point].prev_point; AllT += (poprzedni.guest_count * nextT + poprzedni.time) - t[e.idd].time ; if(poprzedni.guest_count > 1) q.push({ (int) (t[e.idd].time - poprzedni.time) / (poprzedni.guest_count-1) + (((t[e.idd].time - poprzedni.time) % (poprzedni.guest_count -1)) ? 1 : 0) , e.idd, false }); poprzedni.guest_count += t[e.idd].guest_count; t[e.idd].prev_point = -1; ++partial; } else { --partial; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, m; cin >> n >> m; long long int * t_in = new long long int[n]; vector<pointInTime> t; long long int constant_factor = 0; long long int firstT; cin >> firstT; t_in[0] = 0; for (int i = 1; i < n; ++i) { cin >> t_in[i]; t_in[i] -= firstT; } t.push_back({0, 1, -1 }); for (int i = 1; i < n; ++i) { if (t_in[i] == t.back().time) t.back().guest_count++; else { constant_factor += (t.back().guest_count - 1) * t.back().guest_count / 2; t.push_back({ t_in[i], 1, (int)t.size() - 1 }); } } constant_factor += (t.back().guest_count - 1) * t.back().guest_count / 2; delete[] t_in; oven* p = new oven[m]; for (int i = 0; i < m; ++i) { cin >> p[i].bTime; p[i].id = i; } sort(p, p + m); qType q; initialize(t, q); int partial = 0; long long int AllT = 0, curT = 0; long long int * res = new long long int[m]; for (int i = 0; i < m; ++i) { int nextT = p[i].bTime; while (!q.empty() && q.top().minZ <= nextT) { querry(q, curT, AllT, nextT, partial, t); } AllT += partial * (nextT - curT); curT = nextT; res[p[i].id] = AllT + max(0ll, nextT - firstT); } for (int i = 0; i < m; ++i) { cout << res[i] - 1 << "\n"; } }
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 <algorithm> #include <vector> #include <queue> #include <functional> #include <utility> #include <tuple> using namespace std; struct pointInTime { long long int time; int guest_count; int prev_point; inline bool operator <(const pointInTime &p2) const { return time < p2.time; } }; struct oven { int bTime; int id; inline bool operator <(const oven &p2) const { return bTime < p2.bTime; } }; struct Event { int minZ; int idd; bool start; public: bool operator< (const Event &p2) const { return minZ > p2.minZ; } }; typedef priority_queue<Event> qType ; void initialize(vector<pointInTime> t, qType &q) { for (int i = 1; i < (int)t.size(); ++i) { q.push({ (int)(t[i].time - t[i-1].time) / t[i-1].guest_count + (((t[i].time - t[i - 1].time) % (t[i - 1].guest_count)) ? 1:0), i, true }); } } void querry(qType &q, long long &curT, long long &AllT, long long int nextT, int &partial, vector<pointInTime> t) { Event e = q.top(); q.pop(); AllT += partial * (e.minZ - curT); curT = e.minZ; if (e.start) { if (t[e.idd].prev_point == -1) return; pointInTime& poprzedni = t[t[e.idd].prev_point]; if (e.idd + 1 < (int)t.size()) t[e.idd + 1].prev_point = t[t[e.idd].prev_point].prev_point; AllT += (poprzedni.guest_count * nextT + poprzedni.time) - t[e.idd].time ; if(poprzedni.guest_count > 1) q.push({ (int) (t[e.idd].time - poprzedni.time) / (poprzedni.guest_count-1) + (((t[e.idd].time - poprzedni.time) % (poprzedni.guest_count -1)) ? 1 : 0) , e.idd, false }); poprzedni.guest_count += t[e.idd].guest_count; t[e.idd].prev_point = -1; ++partial; } else { --partial; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, m; cin >> n >> m; long long int * t_in = new long long int[n]; vector<pointInTime> t; long long int constant_factor = 0; long long int firstT; cin >> firstT; t_in[0] = 0; for (int i = 1; i < n; ++i) { cin >> t_in[i]; t_in[i] -= firstT; } t.push_back({0, 1, -1 }); for (int i = 1; i < n; ++i) { if (t_in[i] == t.back().time) t.back().guest_count++; else { constant_factor += (t.back().guest_count - 1) * t.back().guest_count / 2; t.push_back({ t_in[i], 1, (int)t.size() - 1 }); } } constant_factor += (t.back().guest_count - 1) * t.back().guest_count / 2; delete[] t_in; oven* p = new oven[m]; for (int i = 0; i < m; ++i) { cin >> p[i].bTime; p[i].id = i; } sort(p, p + m); qType q; initialize(t, q); int partial = 0; long long int AllT = 0, curT = 0; long long int * res = new long long int[m]; for (int i = 0; i < m; ++i) { int nextT = p[i].bTime; while (!q.empty() && q.top().minZ <= nextT) { querry(q, curT, AllT, nextT, partial, t); } AllT += partial * (nextT - curT); curT = nextT; res[p[i].id] = AllT + max(0ll, nextT - firstT); } for (int i = 0; i < m; ++i) { cout << res[i] - 1 << "\n"; } } |