#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <set> using namespace std; int n, m, a, b, poz; long long ile; long long dodac[200005]; long long wartosci[200005]; long long gdzie[200005]; long long result[1000005]; struct liniowa { long long poczatek, koniec; long long a, b; }; liniowa pomoc; vector <liniowa> v; vector <int> kiedy[1000005]; set < pair <int, int> > przedzialy; set < pair <int, int> >::iterator it; int binarka (int x, int y, long long a, long long coeff) { if (x == y) return x; int sr = (x + y) / 2; if (a >= (coeff - v[sr].a) * v[sr].poczatek + v[sr].b) return binarka(x, sr, a, coeff); return binarka(sr + 1, y, a, coeff); } int main () { scanf("%d%d", &n, &m); pomoc.poczatek = 0; pomoc.koniec = 1000000000001LL; pomoc.a = 0; pomoc.b = 0; v.push_back(pomoc); for (long long i = 1; i <= n; ++i) { scanf("%lld", &wartosci[i]); poz = binarka(0, v.size() - 1, wartosci[i], i); while (v.size() > poz + 1) v.pop_back(); if (wartosci[i] >= (i - v[poz].a) * v[poz].koniec + v[poz].b) { gdzie[i] = v[poz].koniec; pomoc.poczatek = 0; pomoc.koniec = v[poz].koniec; pomoc.a = i; pomoc.b = wartosci[i]; v.pop_back(); v.push_back(pomoc); } else { gdzie[i] = (wartosci[i] - v[poz].b) / (i - v[poz].a); v[poz].poczatek = gdzie[i] + 1; pomoc.poczatek = 0; pomoc.koniec = gdzie[i]; pomoc.a = i; pomoc.b = wartosci[i]; v.push_back(pomoc); } if (gdzie[i] <= 1000000) kiedy[gdzie[i] + 1].push_back(i); } for (long long i = 1; i < 200005; ++i) dodac[i] = dodac[i - 1] + i; przedzialy.insert(make_pair(-1, -1)); przedzialy.insert(make_pair(1000005, 1000005)); for (int i = 1; i <= 1000000; ++i) { for (int j = 0; j < kiedy[i].size(); ++j) { ile++; a = b = kiedy[i][j]; it = przedzialy.upper_bound(make_pair(a, b)); if (it->first == kiedy[i][j] + 1) { ile += dodac[it->second - a + 1] - dodac[it->second - it->first + 1] - 1; b = it->second; przedzialy.erase(it); } it = przedzialy.upper_bound(make_pair(a, b)); it--; if (it->second == a - 1) { ile += dodac[b - it->first + 1] - dodac[it->second - it->first + 1] - dodac[b - a + 1]; a = it->first; przedzialy.erase(it); } przedzialy.insert(make_pair(a, b)); result[i] -= ((long long)(kiedy[i][j] - a + 1) - ((long long)(i) * (long long)(kiedy[i][j] - a + 1) + wartosci[a - 1] - wartosci[kiedy[i][j]])) * (long long)(b - kiedy[i][j] + 1); } result[i] += result[i - 1] + ile; } for (int i = 0; i < m; ++i) { scanf("%d", &a); printf("%lld\n", result[a]); } 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 | #include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <set> using namespace std; int n, m, a, b, poz; long long ile; long long dodac[200005]; long long wartosci[200005]; long long gdzie[200005]; long long result[1000005]; struct liniowa { long long poczatek, koniec; long long a, b; }; liniowa pomoc; vector <liniowa> v; vector <int> kiedy[1000005]; set < pair <int, int> > przedzialy; set < pair <int, int> >::iterator it; int binarka (int x, int y, long long a, long long coeff) { if (x == y) return x; int sr = (x + y) / 2; if (a >= (coeff - v[sr].a) * v[sr].poczatek + v[sr].b) return binarka(x, sr, a, coeff); return binarka(sr + 1, y, a, coeff); } int main () { scanf("%d%d", &n, &m); pomoc.poczatek = 0; pomoc.koniec = 1000000000001LL; pomoc.a = 0; pomoc.b = 0; v.push_back(pomoc); for (long long i = 1; i <= n; ++i) { scanf("%lld", &wartosci[i]); poz = binarka(0, v.size() - 1, wartosci[i], i); while (v.size() > poz + 1) v.pop_back(); if (wartosci[i] >= (i - v[poz].a) * v[poz].koniec + v[poz].b) { gdzie[i] = v[poz].koniec; pomoc.poczatek = 0; pomoc.koniec = v[poz].koniec; pomoc.a = i; pomoc.b = wartosci[i]; v.pop_back(); v.push_back(pomoc); } else { gdzie[i] = (wartosci[i] - v[poz].b) / (i - v[poz].a); v[poz].poczatek = gdzie[i] + 1; pomoc.poczatek = 0; pomoc.koniec = gdzie[i]; pomoc.a = i; pomoc.b = wartosci[i]; v.push_back(pomoc); } if (gdzie[i] <= 1000000) kiedy[gdzie[i] + 1].push_back(i); } for (long long i = 1; i < 200005; ++i) dodac[i] = dodac[i - 1] + i; przedzialy.insert(make_pair(-1, -1)); przedzialy.insert(make_pair(1000005, 1000005)); for (int i = 1; i <= 1000000; ++i) { for (int j = 0; j < kiedy[i].size(); ++j) { ile++; a = b = kiedy[i][j]; it = przedzialy.upper_bound(make_pair(a, b)); if (it->first == kiedy[i][j] + 1) { ile += dodac[it->second - a + 1] - dodac[it->second - it->first + 1] - 1; b = it->second; przedzialy.erase(it); } it = przedzialy.upper_bound(make_pair(a, b)); it--; if (it->second == a - 1) { ile += dodac[b - it->first + 1] - dodac[it->second - it->first + 1] - dodac[b - a + 1]; a = it->first; przedzialy.erase(it); } przedzialy.insert(make_pair(a, b)); result[i] -= ((long long)(kiedy[i][j] - a + 1) - ((long long)(i) * (long long)(kiedy[i][j] - a + 1) + wartosci[a - 1] - wartosci[kiedy[i][j]])) * (long long)(b - kiedy[i][j] + 1); } result[i] += result[i - 1] + ile; } for (int i = 0; i < m; ++i) { scanf("%d", &a); printf("%lld\n", result[a]); } return 0; } |