#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <array>
#include <set>
using std::begin;
using std::end;
enum : size_t {
pos = 0, day = 1, height = 2
};
typedef unsigned long long length;
typedef unsigned long long days_numeral;
typedef size_t position;
typedef std::tuple<position, days_numeral, length> mowing;
template<typename T_pos, typename T, typename Function>
T value_bsearch(T_pos p, T_pos q, const T value, Function f, const length mowing_day) {
while(p+1 < q) {
const T temp = p + (q-p)/2;
//std::cerr << "f("<<temp <<", " << mowing_day << ") > " << value << '\n';
if(f(temp, mowing_day) > value) {
q = temp;
}
else {
p = temp;
}
}
if(f(p, mowing_day) <= value) {
p += 1;
}
return p;
}
std::set<mowing> history = {mowing(0,0,0)};
std::vector<unsigned long long> pace;
std::vector<unsigned long long> sum;
length find(const position i, const days_numeral mowing_day) {
auto it = history.upper_bound(std::make_tuple(i, mowing_day, 1000000000001ULL));
--it;
if(it == end(history)) {
return pace[i]*mowing_day;
}
auto last_mowing = std::get<day>(*it);
return std::get<height>(*it) + (mowing_day-last_mowing)*pace[i];
}
template<typename T>
std::tuple<position, unsigned long long> interval(const position p, T it, const days_numeral mowing_day) {
const days_numeral last_mowing = std::get<day>(*it);
const length last_height = std::get<height>(*it);
++it;
days_numeral q;
if(it == std::end(history)) {
q = pace.size()-1;
}
else {
q = std::get<pos>(*it)-1;
}
typedef std::tuple<position, unsigned long long> return_type;
return return_type(q-p+1, static_cast<unsigned long long>(mowing_day - last_mowing)*(sum[q] - (p == 0 ? 0 : sum[p-1])) + last_height*static_cast<unsigned long long>(1+q-p));
}
template<typename T>
std::vector<unsigned long long> prefsum(const T& input) {
unsigned long long sum = 0;
std::vector<unsigned long long> result;
result.reserve(input.size());
for(auto it = input.cbegin(); it != input.cend(); ++it) {
sum += *it;
result.push_back(sum);
}
return result;
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
unsigned n, m;
std:: cin >> n >> m;
pace.reserve(n);
copy_n(std::istream_iterator<unsigned long long>(std::cin), n,
std::back_inserter(pace));
std::sort(begin(pace), end(pace));
std::vector<std::tuple<days_numeral, length>> schedule(m);
for(auto& x : schedule) {
std::cin >> std::get<0>(x) >> std::get<1>(x);
}
sum = prefsum(pace);
for(const auto& mowing_plan : schedule) {
auto temp = value_bsearch(0U, n, std::get<1>(mowing_plan), find, std::get<0>(mowing_plan));
const auto begin_temp = temp;
auto it = history.upper_bound(mowing(temp, 1000000000001, 1000000000001));
--it;
unsigned long long answer = 0;
while(it != std::end(history)) {
size_t interval_size;
unsigned long long add_value;
std::tie(interval_size, add_value) = interval(temp, it, std::get<0>(mowing_plan));
add_value -= static_cast<unsigned long long>(interval_size) * std::get<1>(mowing_plan);
answer += add_value;
if(std::get<pos>(*it) >= begin_temp) {
it = history.erase(it);
}
else {
++it;
}
if(it != std::end(history)) {
temp = std::get<pos>(*it);
}
}
std::cout << answer << '\n';
history.emplace(temp, std::get<0>(mowing_plan), std::get<1>(mowing_plan));
}
}
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 | #include <algorithm> #include <iostream> #include <iterator> #include <vector> #include <array> #include <set> using std::begin; using std::end; enum : size_t { pos = 0, day = 1, height = 2 }; typedef unsigned long long length; typedef unsigned long long days_numeral; typedef size_t position; typedef std::tuple<position, days_numeral, length> mowing; template<typename T_pos, typename T, typename Function> T value_bsearch(T_pos p, T_pos q, const T value, Function f, const length mowing_day) { while(p+1 < q) { const T temp = p + (q-p)/2; //std::cerr << "f("<<temp <<", " << mowing_day << ") > " << value << '\n'; if(f(temp, mowing_day) > value) { q = temp; } else { p = temp; } } if(f(p, mowing_day) <= value) { p += 1; } return p; } std::set<mowing> history = {mowing(0,0,0)}; std::vector<unsigned long long> pace; std::vector<unsigned long long> sum; length find(const position i, const days_numeral mowing_day) { auto it = history.upper_bound(std::make_tuple(i, mowing_day, 1000000000001ULL)); --it; if(it == end(history)) { return pace[i]*mowing_day; } auto last_mowing = std::get<day>(*it); return std::get<height>(*it) + (mowing_day-last_mowing)*pace[i]; } template<typename T> std::tuple<position, unsigned long long> interval(const position p, T it, const days_numeral mowing_day) { const days_numeral last_mowing = std::get<day>(*it); const length last_height = std::get<height>(*it); ++it; days_numeral q; if(it == std::end(history)) { q = pace.size()-1; } else { q = std::get<pos>(*it)-1; } typedef std::tuple<position, unsigned long long> return_type; return return_type(q-p+1, static_cast<unsigned long long>(mowing_day - last_mowing)*(sum[q] - (p == 0 ? 0 : sum[p-1])) + last_height*static_cast<unsigned long long>(1+q-p)); } template<typename T> std::vector<unsigned long long> prefsum(const T& input) { unsigned long long sum = 0; std::vector<unsigned long long> result; result.reserve(input.size()); for(auto it = input.cbegin(); it != input.cend(); ++it) { sum += *it; result.push_back(sum); } return result; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); unsigned n, m; std:: cin >> n >> m; pace.reserve(n); copy_n(std::istream_iterator<unsigned long long>(std::cin), n, std::back_inserter(pace)); std::sort(begin(pace), end(pace)); std::vector<std::tuple<days_numeral, length>> schedule(m); for(auto& x : schedule) { std::cin >> std::get<0>(x) >> std::get<1>(x); } sum = prefsum(pace); for(const auto& mowing_plan : schedule) { auto temp = value_bsearch(0U, n, std::get<1>(mowing_plan), find, std::get<0>(mowing_plan)); const auto begin_temp = temp; auto it = history.upper_bound(mowing(temp, 1000000000001, 1000000000001)); --it; unsigned long long answer = 0; while(it != std::end(history)) { size_t interval_size; unsigned long long add_value; std::tie(interval_size, add_value) = interval(temp, it, std::get<0>(mowing_plan)); add_value -= static_cast<unsigned long long>(interval_size) * std::get<1>(mowing_plan); answer += add_value; if(std::get<pos>(*it) >= begin_temp) { it = history.erase(it); } else { ++it; } if(it != std::end(history)) { temp = std::get<pos>(*it); } } std::cout << answer << '\n'; history.emplace(temp, std::get<0>(mowing_plan), std::get<1>(mowing_plan)); } } |
English