#include <iostream> #include <vector> #include <algorithm> #include <stack> using namespace std; typedef long long ll; #define poka(x) cerr << #x << " = " << x << endl; class trojka{ public: int ind; ll dzien, wys; trojka(int ind, ll dzien, ll wys){ this->ind = ind; this->dzien = dzien; this->wys = wys; } void pokaz(){ cerr << "(ind = " << ind << ", dzien = " << dzien << ", wys = " << wys << ")\n"; } }; ll sp[500*1000+9]; ll sumana(int a, int b){ if(a > b) return 0; if(a==0) return sp[b]; return sp[b]-sp[a-1]; } int main(){ ios_base::sync_with_stdio(0); int traw, dni; cin >> traw >> dni; vector<ll> wzrost(traw); for(int i = 0; i < traw; ++i) cin >> wzrost[i]; sort(wzrost.begin(), wzrost.end()); sp[0] = wzrost[0]; for(int i = 1; i < traw; ++i) sp[i] = sp[i-1] + wzrost[i]; stack<trojka> stos; stos.push(trojka(0,0,0)); while(dni--){ ll dzien, wys; cin >> dzien >> wys; int prawy = traw; ll suma = 0; while(!stos.empty()){ int ind = stos.top().ind; ll czas = dzien - stos.top().dzien; ll wyswtedy = stos.top().wys; ll wysteraz1 = wyswtedy + czas * wzrost[ind]; if(wysteraz1 > wys){ suma += czas * sumana(ind, prawy-1) + (wyswtedy - wys) * ll(prawy - ind); prawy = ind; stos.pop(); } else{ int a = ind, b = prawy; while(a < b){ int m = (a+b)/2; ll wysteraz = wyswtedy + czas * wzrost[m]; if(wysteraz <= wys) a = m+1; else b = m; } if(a != traw) stos.push(trojka(a, dzien, wys)); suma += czas * sumana(a, prawy-1) + (wyswtedy - wys) * ll(prawy - a); break; } } if(stos.empty()) stos.push(trojka(0,dzien,wys)); cout << suma << "\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 | #include <iostream> #include <vector> #include <algorithm> #include <stack> using namespace std; typedef long long ll; #define poka(x) cerr << #x << " = " << x << endl; class trojka{ public: int ind; ll dzien, wys; trojka(int ind, ll dzien, ll wys){ this->ind = ind; this->dzien = dzien; this->wys = wys; } void pokaz(){ cerr << "(ind = " << ind << ", dzien = " << dzien << ", wys = " << wys << ")\n"; } }; ll sp[500*1000+9]; ll sumana(int a, int b){ if(a > b) return 0; if(a==0) return sp[b]; return sp[b]-sp[a-1]; } int main(){ ios_base::sync_with_stdio(0); int traw, dni; cin >> traw >> dni; vector<ll> wzrost(traw); for(int i = 0; i < traw; ++i) cin >> wzrost[i]; sort(wzrost.begin(), wzrost.end()); sp[0] = wzrost[0]; for(int i = 1; i < traw; ++i) sp[i] = sp[i-1] + wzrost[i]; stack<trojka> stos; stos.push(trojka(0,0,0)); while(dni--){ ll dzien, wys; cin >> dzien >> wys; int prawy = traw; ll suma = 0; while(!stos.empty()){ int ind = stos.top().ind; ll czas = dzien - stos.top().dzien; ll wyswtedy = stos.top().wys; ll wysteraz1 = wyswtedy + czas * wzrost[ind]; if(wysteraz1 > wys){ suma += czas * sumana(ind, prawy-1) + (wyswtedy - wys) * ll(prawy - ind); prawy = ind; stos.pop(); } else{ int a = ind, b = prawy; while(a < b){ int m = (a+b)/2; ll wysteraz = wyswtedy + czas * wzrost[m]; if(wysteraz <= wys) a = m+1; else b = m; } if(a != traw) stos.push(trojka(a, dzien, wys)); suma += czas * sumana(a, prawy-1) + (wyswtedy - wys) * ll(prawy - a); break; } } if(stos.empty()) stos.push(trojka(0,dzien,wys)); cout << suma << "\n"; } return 0; } |