#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; } |
English