#include <cstdio>
#include <algorithm>
struct grupa {
unsigned long long dzien;
unsigned long long baza;
unsigned id;
};
unsigned n,m;
unsigned * szybkosc;
unsigned long long * dzien;
unsigned long long * wysokosc;
unsigned long long * suma;
grupa * koszenia;
unsigned nGrup;
unsigned long long aktDzien;
grupa * badana;
bool porownajEl(const unsigned long long & a, const unsigned long long & val) {
return ((badana->baza + (aktDzien-badana->dzien)*a) < val);
}
bool porownajGrupy(const grupa & a, const unsigned long long & b) {
return ((a.baza + (aktDzien - a.dzien)*szybkosc[a.id]) < b);
}
unsigned maxIndex(const grupa * const a) {
unsigned id = a - koszenia + 1;
if (id < nGrup)
return koszenia[id].id;
else
return n;
}
unsigned long long uzysk(const unsigned down, const unsigned up, unsigned long long h, grupa * g) {
unsigned long long dolnaSuma;
if (down == 0)
dolnaSuma = 0;
else
dolnaSuma = suma[down-1];
unsigned long long pozostawione = (up-down) * h;
unsigned long long calosc = (suma[up-1]-dolnaSuma)*(aktDzien - g->dzien) + (up-down)*g->baza;
return calosc - pozostawione;
}
int main(void) {
scanf("%u %u", &n, &m);
szybkosc = new unsigned[n+1];
for (unsigned i=0u; i<n; i++)
scanf("%u", (szybkosc+i));
std::sort(szybkosc, (szybkosc+n));
suma = new unsigned long long[n+1];
suma[0] = szybkosc[0];
for (unsigned i=1; i<n; i++)
suma[i] = szybkosc[i] + suma[i-1];
dzien = new unsigned long long[m+1];
wysokosc = new unsigned long long[m+1];
for (unsigned i=0u; i<m; i++)
scanf("%llu %llu", (dzien+i), (wysokosc+i));
koszenia = new grupa[m+1];
koszenia[0] = {0u, 0u, 0};
nGrup = 1;
for (unsigned i=0u; i<m; i++) {
aktDzien = dzien[i];
grupa * res = std::lower_bound(koszenia, (koszenia+nGrup), wysokosc[i], porownajGrupy);
if ( res == (koszenia+nGrup)) {
res = (koszenia+nGrup-1);
}
unsigned * start = szybkosc+(res->id);
if ((res != koszenia) && (*start >= wysokosc[i])) {
badana = res-1;
auto resMaly = std::lower_bound((szybkosc+badana->id), (szybkosc+res->id), wysokosc[i], porownajEl);
if (*resMaly >= wysokosc[i]) {
start = resMaly;
res = res - 1;
}
} else if (*start < wysokosc[i]) {
badana = res;
unsigned upper_bound = maxIndex(res);
auto resMaly = std::lower_bound((szybkosc+res->id), (szybkosc+upper_bound), wysokosc[i], porownajEl);
if (resMaly == (szybkosc+n)) {
printf("0\n");
continue;
}
start = resMaly;
}
unsigned int indexGrupy = res - koszenia;
unsigned int indexEl = start - szybkosc;
unsigned long long res_suma = uzysk(indexEl, maxIndex(res), wysokosc[i], res);
for (unsigned j = indexGrupy+1; j<nGrup; j++)
res_suma += uzysk(koszenia[j].id, maxIndex(koszenia+j), wysokosc[i], koszenia+j);
printf("%llu\n", res_suma);
if (koszenia[indexGrupy].id == indexEl)
koszenia[indexGrupy] = { dzien[i], wysokosc[i], indexEl };
else {
nGrup = indexGrupy+2;
koszenia[indexGrupy+1] = { dzien[i], wysokosc[i], indexEl };
}
}
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 107 108 109 110 111 112 113 114 115 116 117 | #include <cstdio> #include <algorithm> struct grupa { unsigned long long dzien; unsigned long long baza; unsigned id; }; unsigned n,m; unsigned * szybkosc; unsigned long long * dzien; unsigned long long * wysokosc; unsigned long long * suma; grupa * koszenia; unsigned nGrup; unsigned long long aktDzien; grupa * badana; bool porownajEl(const unsigned long long & a, const unsigned long long & val) { return ((badana->baza + (aktDzien-badana->dzien)*a) < val); } bool porownajGrupy(const grupa & a, const unsigned long long & b) { return ((a.baza + (aktDzien - a.dzien)*szybkosc[a.id]) < b); } unsigned maxIndex(const grupa * const a) { unsigned id = a - koszenia + 1; if (id < nGrup) return koszenia[id].id; else return n; } unsigned long long uzysk(const unsigned down, const unsigned up, unsigned long long h, grupa * g) { unsigned long long dolnaSuma; if (down == 0) dolnaSuma = 0; else dolnaSuma = suma[down-1]; unsigned long long pozostawione = (up-down) * h; unsigned long long calosc = (suma[up-1]-dolnaSuma)*(aktDzien - g->dzien) + (up-down)*g->baza; return calosc - pozostawione; } int main(void) { scanf("%u %u", &n, &m); szybkosc = new unsigned[n+1]; for (unsigned i=0u; i<n; i++) scanf("%u", (szybkosc+i)); std::sort(szybkosc, (szybkosc+n)); suma = new unsigned long long[n+1]; suma[0] = szybkosc[0]; for (unsigned i=1; i<n; i++) suma[i] = szybkosc[i] + suma[i-1]; dzien = new unsigned long long[m+1]; wysokosc = new unsigned long long[m+1]; for (unsigned i=0u; i<m; i++) scanf("%llu %llu", (dzien+i), (wysokosc+i)); koszenia = new grupa[m+1]; koszenia[0] = {0u, 0u, 0}; nGrup = 1; for (unsigned i=0u; i<m; i++) { aktDzien = dzien[i]; grupa * res = std::lower_bound(koszenia, (koszenia+nGrup), wysokosc[i], porownajGrupy); if ( res == (koszenia+nGrup)) { res = (koszenia+nGrup-1); } unsigned * start = szybkosc+(res->id); if ((res != koszenia) && (*start >= wysokosc[i])) { badana = res-1; auto resMaly = std::lower_bound((szybkosc+badana->id), (szybkosc+res->id), wysokosc[i], porownajEl); if (*resMaly >= wysokosc[i]) { start = resMaly; res = res - 1; } } else if (*start < wysokosc[i]) { badana = res; unsigned upper_bound = maxIndex(res); auto resMaly = std::lower_bound((szybkosc+res->id), (szybkosc+upper_bound), wysokosc[i], porownajEl); if (resMaly == (szybkosc+n)) { printf("0\n"); continue; } start = resMaly; } unsigned int indexGrupy = res - koszenia; unsigned int indexEl = start - szybkosc; unsigned long long res_suma = uzysk(indexEl, maxIndex(res), wysokosc[i], res); for (unsigned j = indexGrupy+1; j<nGrup; j++) res_suma += uzysk(koszenia[j].id, maxIndex(koszenia+j), wysokosc[i], koszenia+j); printf("%llu\n", res_suma); if (koszenia[indexGrupy].id == indexEl) koszenia[indexGrupy] = { dzien[i], wysokosc[i], indexEl }; else { nGrup = indexGrupy+2; koszenia[indexGrupy+1] = { dzien[i], wysokosc[i], indexEl }; } } return 0; } |
English