Pagini recente » Cod sursa (job #2308793) | Cod sursa (job #3250547) | Cod sursa (job #1704012) | Cod sursa (job #2890327) | Cod sursa (job #1971117)
#include <bits/stdc++.h>
using namespace std;
#define REP(i,a) for (int i = 0; i < a; i++)
#define FOR(i,a,b) for (int i = a; i <= b; i++)
#define ROF(i,a,b) for (int i = a; i >= b; i--)
#define FOREACH(it,x) for (auto it: (x))
#define SZ(x) ((int)(x).size())
#define ll long long
#define iter set<Line>::iterator
const ll inf = 1LL<<62;
struct Line {
ll a,b,val;
bool is_query;
double xlo;
Line(ll _a,ll _b,ll _val,bool _is_query): a(_a),b(_b),is_query(_is_query),val(_val),xlo(-inf) {}
bool operator<(Line Other) const {
if (Other.is_query)
return xlo - Other.val < -0.00000001;
if (a == Other.a)
return b < Other.b;
return a < Other.a;
}
double intersect(Line Other) const {
assert(a != Other.a);
return 1.0 * (Other.b - b) / (a - Other.a);
}
};
class HullTrick {
public:
HullTrick() {}
void Insert(Line l) {
iter it = hull.insert(l).first;
if (useless(it)) {
hull.erase(it);
return;
}
iter it1 = it,it2 = it;
while (has_prev(it1) && useless(--it1)) hull.erase(it1++);
while (has_next(it2) && useless(++it2)) hull.erase(it2--);
if (has_prev(it)) update_left_border(it);
if (has_next(it)) update_left_border(++it);
}
ll Query(ll x) {
Line l = Line(0,0,x,true);
iter it = hull.lower_bound(l);
--it;
return it->a * x + it->b;
}
private:
set<Line> hull;
inline bool has_prev(iter it) const {
return it != hull.begin();
}
inline bool has_next(iter it) const {
return (it != hull.end()) && (++it != hull.end());
}
bool useless(iter it) const {
if (!has_next(it) || !has_prev(it))
return false;
iter next = it, prev = it;
next++; prev--;
return prev->intersect(*next) <= prev->intersect(*it);
}
void update_left_border(iter it) {
if (!has_prev(it)) return;
iter prev = it; --prev;
double where = it->intersect(*prev);
Line l(*it);
l.xlo = where;
hull.erase(it++);
hull.insert(it,l);
}
};
HullTrick ht;
ll sum[35000];
ll B[35000];
int main()
{
ifstream fin("euro.in");
ofstream fout("euro.out");
int n; ll T;
fin >> n >> T;
sum[0] = 0;
ht.Insert(Line(0,0,0,false));
FOR(i,1,n) {
fin >> sum[i]; sum[i] += sum[i-1];
B[i] = ht.Query(i) + sum[i] * i - T;
ht.Insert(Line(-sum[i],B[i],0,false));
}
fout << B[n];
}