#include <algorithm> #include <functional> #include <iostream> #include <vector> using namespace std; namespace { struct Cut { long long day; long long height; int end; Cut(long long d, long long h, int e): day{d}, height{h}, end{e} { } }; template <typename Fun> int find_first(int a, int b, Fun&& f) { if (f(a)) return a; if (!f(b)) return b+1; while (b-a > 1) { int x = (a+b) / 2; if (f(x)) b = x; else a = x; } return b; } class Field { private: vector<int> growth; vector<long long> sum_growth; vector<Cut> cuts; public: Field(vector<int> growth_): growth{move(growth_)} { sort(growth.begin(), growth.end(), greater<int>()); cuts.emplace_back(0, 0, growth.size()); sum_growth.reserve(growth.size() + 1); sum_growth.push_back(0); for (auto const& g: growth) { sum_growth.push_back(sum_growth.back() + g); } } long long sum(int b, int e) { return sum_growth[e] - sum_growth[b]; } long long cut(long long day, long long height) { long long res = 0; auto start = 0; while (!cuts.empty()) { auto const& c = cuts.back(); int x = find_first(start, c.end-1, [&](int i) { return c.height + growth[i] * (day - c.day) < height; }); res += (day - c.day) * sum(start, x); res -= (height - c.height) * (x - start); if (x < c.end) { if (x > 0) { cuts.emplace_back(day, height, x); } break; } start = c.end; cuts.pop_back(); } if (cuts.empty()) { cuts.emplace_back(day, height, growth.size()); } return res; } }; } int main() { iostream::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<int> growth(n); for (auto& a: growth) { cin >> a; } Field f{move(growth)}; for (int i = 0; i < m; ++i) { long long d, b; cin >> d >> b; cout << f.cut(d, b) << '\n'; } 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 | #include <algorithm> #include <functional> #include <iostream> #include <vector> using namespace std; namespace { struct Cut { long long day; long long height; int end; Cut(long long d, long long h, int e): day{d}, height{h}, end{e} { } }; template <typename Fun> int find_first(int a, int b, Fun&& f) { if (f(a)) return a; if (!f(b)) return b+1; while (b-a > 1) { int x = (a+b) / 2; if (f(x)) b = x; else a = x; } return b; } class Field { private: vector<int> growth; vector<long long> sum_growth; vector<Cut> cuts; public: Field(vector<int> growth_): growth{move(growth_)} { sort(growth.begin(), growth.end(), greater<int>()); cuts.emplace_back(0, 0, growth.size()); sum_growth.reserve(growth.size() + 1); sum_growth.push_back(0); for (auto const& g: growth) { sum_growth.push_back(sum_growth.back() + g); } } long long sum(int b, int e) { return sum_growth[e] - sum_growth[b]; } long long cut(long long day, long long height) { long long res = 0; auto start = 0; while (!cuts.empty()) { auto const& c = cuts.back(); int x = find_first(start, c.end-1, [&](int i) { return c.height + growth[i] * (day - c.day) < height; }); res += (day - c.day) * sum(start, x); res -= (height - c.height) * (x - start); if (x < c.end) { if (x > 0) { cuts.emplace_back(day, height, x); } break; } start = c.end; cuts.pop_back(); } if (cuts.empty()) { cuts.emplace_back(day, height, growth.size()); } return res; } }; } int main() { iostream::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<int> growth(n); for (auto& a: growth) { cin >> a; } Field f{move(growth)}; for (int i = 0; i < m; ++i) { long long d, b; cin >> d >> b; cout << f.cut(d, b) << '\n'; } return 0; } |