#include <cstdio> #include <algorithm> #include <set> #include <queue> long long tab[200007]; std::pair<int, int> d[200007]; std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>> Q; std::set<std::pair<long long, int>> s; long long prawo[200007]; int ile[200007]; int poprz[200007]; long long obl[200007]; long long suml[200007]; long long wyniki[200007]; long long sumrel[200007]; int main() { int N, M; scanf("%d%d", &N, &M); s.insert({0, 0}); for (int i = 1; i <= N; i++) { scanf("%lld", &tab[i]); obl[i] = tab[i] - tab[i - 1]; Q.push({obl[i], i}); poprz[i] = i - 1; s.insert({tab[i], i}); suml[i] = suml[i - 1] + i; } for (int i = 0; i < M; i++) { scanf("%d", &d[i].first); d[i].second = i; } std::sort(d, d + M); int q = 0; long long sum = 0; long long sum2 = 0; while (!Q.empty()) { long long zeit = Q.top().first; int ter = Q.top().second; Q.pop(); if (obl[ter] != zeit) continue; while (q < M && zeit > d[q].first) { wyniki[d[q].second] = sum * d[q].first - sum2; q++; } obl[ter] = -1; s.erase({tab[ter], ter}); int p = poprz[ter]; // printf("Lacze %d z %d\n", p, ter); sum2 -= sumrel[ter]; sum2 -= sumrel[p]; sumrel[p] += (ile[ter] + 1) * (tab[ter] - tab[p]) + sumrel[ter]; sum2 += sumrel[p]; sum -= suml[ile[ter]]; sum -= suml[ile[p]]; ile[p] += ile[ter] + 1; sum += suml[ile[p]]; prawo[p] = zeit * ile[p]; // printf("ile = %d, prawo = %lld\n", ile[p], prawo[p]); auto next = s.upper_bound({tab[ter], ter}); if (next != s.end()) { ter = next->second; // printf("Sprawdzam czas laczenia %d (%lld) z %d (%lld)\n", p, tab[p], ter, tab[ter]); long long odl = (tab[ter] - tab[p] - prawo[p] - zeit); // printf("Prawo[%d] = %lld, Lewo[%d] = %lld\n", p, prawo[p], ter, lewo[ter]); // printf("Odl = %lld\n", odl); long long czas = zeit + ((odl + ile[p]) / (ile[p] + 1)); czas = std::max(czas, zeit); obl[ter] = czas; poprz[ter] = p; // printf("Wrzucam nowy czas %lld\n", czas); Q.push({czas, ter}); } } while (q < M) { wyniki[d[q].second] = sum * d[q].first - sum2; q++; } for (int i = 0; i < M; i++) { printf("%lld\n", wyniki[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 | #include <cstdio> #include <algorithm> #include <set> #include <queue> long long tab[200007]; std::pair<int, int> d[200007]; std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>> Q; std::set<std::pair<long long, int>> s; long long prawo[200007]; int ile[200007]; int poprz[200007]; long long obl[200007]; long long suml[200007]; long long wyniki[200007]; long long sumrel[200007]; int main() { int N, M; scanf("%d%d", &N, &M); s.insert({0, 0}); for (int i = 1; i <= N; i++) { scanf("%lld", &tab[i]); obl[i] = tab[i] - tab[i - 1]; Q.push({obl[i], i}); poprz[i] = i - 1; s.insert({tab[i], i}); suml[i] = suml[i - 1] + i; } for (int i = 0; i < M; i++) { scanf("%d", &d[i].first); d[i].second = i; } std::sort(d, d + M); int q = 0; long long sum = 0; long long sum2 = 0; while (!Q.empty()) { long long zeit = Q.top().first; int ter = Q.top().second; Q.pop(); if (obl[ter] != zeit) continue; while (q < M && zeit > d[q].first) { wyniki[d[q].second] = sum * d[q].first - sum2; q++; } obl[ter] = -1; s.erase({tab[ter], ter}); int p = poprz[ter]; // printf("Lacze %d z %d\n", p, ter); sum2 -= sumrel[ter]; sum2 -= sumrel[p]; sumrel[p] += (ile[ter] + 1) * (tab[ter] - tab[p]) + sumrel[ter]; sum2 += sumrel[p]; sum -= suml[ile[ter]]; sum -= suml[ile[p]]; ile[p] += ile[ter] + 1; sum += suml[ile[p]]; prawo[p] = zeit * ile[p]; // printf("ile = %d, prawo = %lld\n", ile[p], prawo[p]); auto next = s.upper_bound({tab[ter], ter}); if (next != s.end()) { ter = next->second; // printf("Sprawdzam czas laczenia %d (%lld) z %d (%lld)\n", p, tab[p], ter, tab[ter]); long long odl = (tab[ter] - tab[p] - prawo[p] - zeit); // printf("Prawo[%d] = %lld, Lewo[%d] = %lld\n", p, prawo[p], ter, lewo[ter]); // printf("Odl = %lld\n", odl); long long czas = zeit + ((odl + ile[p]) / (ile[p] + 1)); czas = std::max(czas, zeit); obl[ter] = czas; poprz[ter] = p; // printf("Wrzucam nowy czas %lld\n", czas); Q.push({czas, ter}); } } while (q < M) { wyniki[d[q].second] = sum * d[q].first - sum2; q++; } for (int i = 0; i < M; i++) { printf("%lld\n", wyniki[i]); } return 0; } |