Pagini recente » Cod sursa (job #114109) | Cod sursa (job #282403) | Cod sursa (job #1097420) | Cod sursa (job #2259863) | Cod sursa (job #1989357)
#include <fstream>
#include <cmath>
#include <set>
using namespace std;
ifstream fin ("euro.in"); ofstream fout ("euro.out");
typedef long long i64;
const int nmax = 34570;
i64 d[nmax + 1];
struct dreapta {
i64 a, b;
dreapta() {}
dreapta (i64 _a, i64 _b) {
a = _a, b = _b;
}
inline bool operator < (const dreapta &x) const {
if (b != x.b) return (b > x.b);
return (a > x.a);
}
};
set< dreapta > s;
set< dreapta >::iterator it;
long double intersect (dreapta d1, dreapta d2) { /// cand d2 il ia pe d1
if (d1.a == d2.a) {
return INFINITY;
}
long double x = (long double)(d2.b - d1.b) / (d1.a - d2.a);
if (x < 0) return INFINITY;
return x;
}
void baga (dreapta x) {
if (s.find( x ) != s.end()) return ;
set< dreapta >::iterator u = s.insert( x ).first;
set< dreapta >::iterator top1, top2, last;
top1 = u; last = u;
if (u != s.begin()) {
top2 = top1; -- top2;
while (top1 != s.begin()) {
top1 = top2;
last = top1;
if (top1 == s.begin()) {
if (intersect(*top1, x) == INFINITY) {
s.erase( x );
}
break;
}
top2 = top1; -- top2;
if (intersect(*top1, x) <= intersect(*top2, *top1)) {
if (it == top1) -- it;
s.erase(top1);
} else {
break;
}
}
}
top1 = last;
top2 = last; ++ top2;
if (top1 != s.end()) {
while (top1 != s.end()) {
top1 = top2;
if (top1 == s.end()) break;
++ top2;
if (top2 == s.end()) {
if (intersect(*last, *top1) == INFINITY) {
s.erase(top1);
}
break;
}
if (intersect(*top1, *top2) <= intersect(*last, *top1)) {
s.erase(top1);
} else {
break;
}
}
}
}
int main() {
int n, t;
fin >> n >> t;
s.insert(dreapta(0, 0));
i64 sum = 0;
for (int i = 1; i <= n; ++ i) {
i64 x;
fin >> x;
sum += x;
d[ i ] = (s.begin() -> a) * i + (s.begin() -> b) + sum * i - t;
dreapta aux = dreapta(-sum, d[ i ]);
baga( aux );
while (s.size() > 1) {
set< dreapta >::iterator it = s.begin();
++ it;
if (intersect(*s.begin(), *it) < i + 1) {
s.erase(s.begin());
} else {
break;
}
}
}
fout << d[ n ] << "\n";
fin.close();
fout.close();
return 0;
}