#include <cstdio> #include <vector> #include <map> #include <algorithm> using namespace std; int a, n, m; vector<long long> v, sum; //v_rosn, sumy_prefix long long d, b; map<long long, long long> d_wys; //mapa dzien -> sciecie vector<pair<long long, long long> > stos; //stos cięć, zawiera id początku ścięcia void dodaj(pair<long long, long long> p) { while(!stos.empty() && stos.back().second >= p.second) { stos.pop_back(); } stos.push_back(p); } long long ost_ciecie(int id) { //to da się zrobić lepiej int s = stos.size() - 1; while(s >= 0 && stos[s].second > id) { s--; } if(s >= 0) return stos[s].first; return 0; } long long oblicz_wynik(int id, long long d) { long long wynik = 0; int s = stos.size() - 1; int ost = n; while(s >= 0 && stos[s].second >= id) { wynik = wynik + (d - stos[s].first) * (sum[ost] - sum[stos[s].second]); wynik = wynik + d_wys[stos[s].first] * (ost - stos[s].second); ost = stos[s].second; s--; } if(ost != id) wynik = wynik + d * (sum[ost] - sum[id]) ; if(!stos.empty() && s >= 0) { wynik = wynik - stos[s].first * (sum[ost] - sum[id]); wynik = wynik + d_wys[stos[s].first] * (ost - id); } return wynik; } int binary_search(int p, int k, long long d, long long b) { int curr_score = 500001; while(p < k) { int x = (p+k)/2; if (( (d - ost_ciecie(x))*v[x] + d_wys[ost_ciecie(x)]) > b) { k = x; curr_score = min(curr_score, x); } else { p = x + 1; } } return curr_score; } int main() { scanf("%d%d",&n,&m); for(int i = 0; i < n; ++i) { scanf("%d",&a); v.push_back(a); } sort(v.begin(), v.end()); sum.push_back(0); for(int i = 0; i < n; ++i){ sum.push_back(sum.back() + v[i]); } for(int i = 0; i < m; ++i) { scanf("%lld%lld",&d, &b); d_wys[d] = b; long long wynik = 0; int x = binary_search(0, n-1, d , b); if(x != 500001) { wynik = oblicz_wynik(x, d); wynik = wynik - b * (n - x); dodaj(make_pair(d, x)); } printf("%lld\n", wynik); } 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 | #include <cstdio> #include <vector> #include <map> #include <algorithm> using namespace std; int a, n, m; vector<long long> v, sum; //v_rosn, sumy_prefix long long d, b; map<long long, long long> d_wys; //mapa dzien -> sciecie vector<pair<long long, long long> > stos; //stos cięć, zawiera id początku ścięcia void dodaj(pair<long long, long long> p) { while(!stos.empty() && stos.back().second >= p.second) { stos.pop_back(); } stos.push_back(p); } long long ost_ciecie(int id) { //to da się zrobić lepiej int s = stos.size() - 1; while(s >= 0 && stos[s].second > id) { s--; } if(s >= 0) return stos[s].first; return 0; } long long oblicz_wynik(int id, long long d) { long long wynik = 0; int s = stos.size() - 1; int ost = n; while(s >= 0 && stos[s].second >= id) { wynik = wynik + (d - stos[s].first) * (sum[ost] - sum[stos[s].second]); wynik = wynik + d_wys[stos[s].first] * (ost - stos[s].second); ost = stos[s].second; s--; } if(ost != id) wynik = wynik + d * (sum[ost] - sum[id]) ; if(!stos.empty() && s >= 0) { wynik = wynik - stos[s].first * (sum[ost] - sum[id]); wynik = wynik + d_wys[stos[s].first] * (ost - id); } return wynik; } int binary_search(int p, int k, long long d, long long b) { int curr_score = 500001; while(p < k) { int x = (p+k)/2; if (( (d - ost_ciecie(x))*v[x] + d_wys[ost_ciecie(x)]) > b) { k = x; curr_score = min(curr_score, x); } else { p = x + 1; } } return curr_score; } int main() { scanf("%d%d",&n,&m); for(int i = 0; i < n; ++i) { scanf("%d",&a); v.push_back(a); } sort(v.begin(), v.end()); sum.push_back(0); for(int i = 0; i < n; ++i){ sum.push_back(sum.back() + v[i]); } for(int i = 0; i < m; ++i) { scanf("%lld%lld",&d, &b); d_wys[d] = b; long long wynik = 0; int x = binary_search(0, n-1, d , b); if(x != 500001) { wynik = oblicz_wynik(x, d); wynik = wynik - b * (n - x); dodaj(make_pair(d, x)); } printf("%lld\n", wynik); } return 0; } |