#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; using namespace std; #ifdef LOCAL template <class T, class U> ostream& operator<<(ostream& os, pair<T, U> p) { return os << "(" << p.first << ", " << p.second << ")"; } template<template<class, class...> class C, class... A> typename enable_if<!is_same<C<A...>, string>::value, ostream&>::type operator<<(ostream& os, C<A...> c) { auto i = c.begin(); while (i != c.end()) { os << " {"[i == c.begin()] << *i; os << ",}"[++i == c.end()]; } return os; } #define debug(x) { cerr << #x << " = " << x << endl; } #else #define debug(...) {} #endif template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; const int N = 200 * 1000 + 5; int size[N]; long long begining[N]; long long ending[N]; int last_event[N]; ordered_set<pair<long long, int>> clients; #ifdef LOCAL const int T = 10; #else const int T = 1000 * 1000 + 6; #endif vector<int> zda[T]; long long ans[T]; long long wzo(int x) { return ((long long)x * (x-1)) / 2; } int main() { int n, m; scanf("%d%d", &n, &m); clients.insert({0, 0}); size[0] = 1; for (int i = 1; i <= n; i ++) { long long a; scanf("%lld", &a); size[i] = 1; begining[i] = a; ending[i] = a; clients.insert({a, i}); } pair<long long,int> last = {-1, -1}; for (auto now : clients) { if (last.second != -1) { if (now.first - last.first < T) zda[now.first - last.first].push_back(last.second); } last = now; } long long wynik = 0; long long delta = 0; for (int t = 0; t < T; t ++) { for (int i = 0; i < zda[t].size(); i ++) { auto x = zda[t][i]; ending[x] += (long long)size[x] * (t - last_event[x]); last_event[x] = t; if (size[x] == 0) continue; debug(x); int k = clients.order_of_key({begining[x], x}); auto nast = *clients.find_by_order(k + 1); assert(begining[nast.second] <= ending[x]); wynik += (ending[x] - begining[nast.second]) * (long long)size[nast.second]; clients.erase(nast); int y = nast.second; ending[y] += (long long)size[y] * (t - last_event[y]); ending[y] += ending[x] - begining[y]; ending[x] = ending[y]; delta -= wzo(size[x]); delta -= wzo(size[y]); size[x] += size[y]; delta += wzo(size[x]); size[y] = 0; if ((int)clients.size() > k + 1) { nast = *clients.find_by_order(k + 1); if (t + (nast.first - ending[x] + size[x] - 1) / size[x] < T) zda[t + (nast.first - ending[x] + size[x] - 1) / size[x]].push_back(x); } } ans[t] = wynik; debug(t); debug(wynik); debug(clients.size()); wynik += delta; } for (int i = 0; i < m; i ++) { int t; scanf("%d", &t); printf("%lld\n", ans[t]); } }
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 | #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; using namespace std; #ifdef LOCAL template <class T, class U> ostream& operator<<(ostream& os, pair<T, U> p) { return os << "(" << p.first << ", " << p.second << ")"; } template<template<class, class...> class C, class... A> typename enable_if<!is_same<C<A...>, string>::value, ostream&>::type operator<<(ostream& os, C<A...> c) { auto i = c.begin(); while (i != c.end()) { os << " {"[i == c.begin()] << *i; os << ",}"[++i == c.end()]; } return os; } #define debug(x) { cerr << #x << " = " << x << endl; } #else #define debug(...) {} #endif template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; const int N = 200 * 1000 + 5; int size[N]; long long begining[N]; long long ending[N]; int last_event[N]; ordered_set<pair<long long, int>> clients; #ifdef LOCAL const int T = 10; #else const int T = 1000 * 1000 + 6; #endif vector<int> zda[T]; long long ans[T]; long long wzo(int x) { return ((long long)x * (x-1)) / 2; } int main() { int n, m; scanf("%d%d", &n, &m); clients.insert({0, 0}); size[0] = 1; for (int i = 1; i <= n; i ++) { long long a; scanf("%lld", &a); size[i] = 1; begining[i] = a; ending[i] = a; clients.insert({a, i}); } pair<long long,int> last = {-1, -1}; for (auto now : clients) { if (last.second != -1) { if (now.first - last.first < T) zda[now.first - last.first].push_back(last.second); } last = now; } long long wynik = 0; long long delta = 0; for (int t = 0; t < T; t ++) { for (int i = 0; i < zda[t].size(); i ++) { auto x = zda[t][i]; ending[x] += (long long)size[x] * (t - last_event[x]); last_event[x] = t; if (size[x] == 0) continue; debug(x); int k = clients.order_of_key({begining[x], x}); auto nast = *clients.find_by_order(k + 1); assert(begining[nast.second] <= ending[x]); wynik += (ending[x] - begining[nast.second]) * (long long)size[nast.second]; clients.erase(nast); int y = nast.second; ending[y] += (long long)size[y] * (t - last_event[y]); ending[y] += ending[x] - begining[y]; ending[x] = ending[y]; delta -= wzo(size[x]); delta -= wzo(size[y]); size[x] += size[y]; delta += wzo(size[x]); size[y] = 0; if ((int)clients.size() > k + 1) { nast = *clients.find_by_order(k + 1); if (t + (nast.first - ending[x] + size[x] - 1) / size[x] < T) zda[t + (nast.first - ending[x] + size[x] - 1) / size[x]].push_back(x); } } ans[t] = wynik; debug(t); debug(wynik); debug(clients.size()); wynik += delta; } for (int i = 0; i < m; i ++) { int t; scanf("%d", &t); printf("%lld\n", ans[t]); } } |