#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
struct schodek {
int poczatek;
long long dzien, wysokosc;
schodek(int poczatek, long long dzien, long long wysokosc) {
this->poczatek = poczatek;
this->dzien = dzien;
this->wysokosc = wysokosc;
}
};
vector<int> szybkosc;
vector<long long> sumy_prefiksowe_szybkosci;
vector<schodek> schodki;
long long wysokosc_trawy(int nr_schodka, int pozycja, long long dzien) {
return schodki[nr_schodka].wysokosc + (dzien - schodki[nr_schodka].dzien) * szybkosc[pozycja];
}
long long suma_wysokosci(int nr_schodka, int pocz, int kon, long long dzien, long long wys) {
return (kon - pocz + 1) * (schodki[nr_schodka].wysokosc - wys) +
(sumy_prefiksowe_szybkosci[kon] - sumy_prefiksowe_szybkosci[pocz] + szybkosc[pocz]) * (dzien - schodki[nr_schodka].dzien);
}
int koniec_schodka(int nr_schodka) {
if (nr_schodka == schodki.size() - 1)
return szybkosc.size() - 1;
return schodki[nr_schodka + 1].poczatek - 1;
}
long long rozwiaz(long long dzien, long long wys) {
if (wys >= wysokosc_trawy(schodki.size() - 1, szybkosc.size() - 1, dzien))
return 0;
int nr_schodka = schodki.size() - 1;
while (nr_schodka > 0 && wys <= wysokosc_trawy(nr_schodka, schodki[nr_schodka].poczatek, dzien))
nr_schodka--;
if (nr_schodka < schodki.size() - 1 && wys > wysokosc_trawy(nr_schodka, schodki[nr_schodka + 1].poczatek - 1, dzien))
nr_schodka++;
int lewy = schodki[nr_schodka].poczatek;
int prawy = koniec_schodka(nr_schodka);
while (lewy < prawy) {
int x = (lewy + prawy) / 2;
if (wys > wysokosc_trawy(nr_schodka, x, dzien))
lewy = x + 1;
else
prawy = x;
}
long long suma = 0;
suma += suma_wysokosci(nr_schodka, lewy, koniec_schodka(nr_schodka), dzien, wys);
for (int i = nr_schodka + 1; i < schodki.size(); ++i)
suma += suma_wysokosci(i, schodki[i].poczatek, koniec_schodka(i), dzien, wys);
int koncowy = schodki.size() - 1;
int poczatkowy = nr_schodka + 1;
if (lewy == schodki[nr_schodka].poczatek)
poczatkowy = nr_schodka;
for (int i = koncowy; i >= poczatkowy; --i)
schodki.pop_back();
schodki.push_back(schodek(lewy, dzien, wys));
return suma;
}
int main() {
int n, m, i;
long long dzien, wys;
scanf("%d%d", &n, &m);
szybkosc.resize(n, 0);
sumy_prefiksowe_szybkosci.resize(n, 0);
for (i = 0; i < n; ++i)
scanf("%d", &szybkosc[i]);
sort(szybkosc.begin(), szybkosc.end());
sumy_prefiksowe_szybkosci[0] = szybkosc[0];
for (i = 1; i < n; ++i)
sumy_prefiksowe_szybkosci[i] = sumy_prefiksowe_szybkosci[i - 1] + szybkosc[i];
schodki.push_back(schodek(0, 0, 0));
for (i = 0; i < m; ++i) {
scanf("%lld%lld", &dzien, &wys);
printf("%lld\n", rozwiaz(dzien, wys));
}
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 | #include <cstdio> #include <algorithm> #include <vector> using namespace std; struct schodek { int poczatek; long long dzien, wysokosc; schodek(int poczatek, long long dzien, long long wysokosc) { this->poczatek = poczatek; this->dzien = dzien; this->wysokosc = wysokosc; } }; vector<int> szybkosc; vector<long long> sumy_prefiksowe_szybkosci; vector<schodek> schodki; long long wysokosc_trawy(int nr_schodka, int pozycja, long long dzien) { return schodki[nr_schodka].wysokosc + (dzien - schodki[nr_schodka].dzien) * szybkosc[pozycja]; } long long suma_wysokosci(int nr_schodka, int pocz, int kon, long long dzien, long long wys) { return (kon - pocz + 1) * (schodki[nr_schodka].wysokosc - wys) + (sumy_prefiksowe_szybkosci[kon] - sumy_prefiksowe_szybkosci[pocz] + szybkosc[pocz]) * (dzien - schodki[nr_schodka].dzien); } int koniec_schodka(int nr_schodka) { if (nr_schodka == schodki.size() - 1) return szybkosc.size() - 1; return schodki[nr_schodka + 1].poczatek - 1; } long long rozwiaz(long long dzien, long long wys) { if (wys >= wysokosc_trawy(schodki.size() - 1, szybkosc.size() - 1, dzien)) return 0; int nr_schodka = schodki.size() - 1; while (nr_schodka > 0 && wys <= wysokosc_trawy(nr_schodka, schodki[nr_schodka].poczatek, dzien)) nr_schodka--; if (nr_schodka < schodki.size() - 1 && wys > wysokosc_trawy(nr_schodka, schodki[nr_schodka + 1].poczatek - 1, dzien)) nr_schodka++; int lewy = schodki[nr_schodka].poczatek; int prawy = koniec_schodka(nr_schodka); while (lewy < prawy) { int x = (lewy + prawy) / 2; if (wys > wysokosc_trawy(nr_schodka, x, dzien)) lewy = x + 1; else prawy = x; } long long suma = 0; suma += suma_wysokosci(nr_schodka, lewy, koniec_schodka(nr_schodka), dzien, wys); for (int i = nr_schodka + 1; i < schodki.size(); ++i) suma += suma_wysokosci(i, schodki[i].poczatek, koniec_schodka(i), dzien, wys); int koncowy = schodki.size() - 1; int poczatkowy = nr_schodka + 1; if (lewy == schodki[nr_schodka].poczatek) poczatkowy = nr_schodka; for (int i = koncowy; i >= poczatkowy; --i) schodki.pop_back(); schodki.push_back(schodek(lewy, dzien, wys)); return suma; } int main() { int n, m, i; long long dzien, wys; scanf("%d%d", &n, &m); szybkosc.resize(n, 0); sumy_prefiksowe_szybkosci.resize(n, 0); for (i = 0; i < n; ++i) scanf("%d", &szybkosc[i]); sort(szybkosc.begin(), szybkosc.end()); sumy_prefiksowe_szybkosci[0] = szybkosc[0]; for (i = 1; i < n; ++i) sumy_prefiksowe_szybkosci[i] = sumy_prefiksowe_szybkosci[i - 1] + szybkosc[i]; schodki.push_back(schodek(0, 0, 0)); for (i = 0; i < m; ++i) { scanf("%lld%lld", &dzien, &wys); printf("%lld\n", rozwiaz(dzien, wys)); } return 0; } |
English