#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; } |
English