Pagini recente » Cod sursa (job #2959465) | Cod sursa (job #2506244) | Cod sursa (job #3189102) | Cod sursa (job #1624993) | Cod sursa (job #8417)
Cod sursa(job #8417)
#include <stdio.h>
#include <algorithm>
#include <set>
#define EPS 1e-5
#define NMax 35000
using namespace std;
double eps=1e-8;
struct line {
long long a, b;
line(){}
line(long long t1, long long t2):a(t1), b(t2){}
};
int N, T;
long long S[NMax], M[NMax];
set<line> s;
line last_line;
double last_x;
bool operator<(const line& l1, const line& l2)
{ return l1.b < l2.b; }
double xinter(const line& l1,const line& l2)
{
return double(l1.a-l2.a)/double(l2.b-l1.b);
}
double yinter(const line& l1,double x)
{
return l1.b*x+l1.a;
}
double best(double x)
{
double ans=-1e12;
set<line>::iterator it=s.find(last_line);
while (it!=s.end() && yinter(*it,x)>ans){
ans=yinter(*it,x);
++it;
}
--it;
last_x=x;
last_line=*it;
return ans;
}
void insereaza(const line& l)
{
while (true){
set<line>::iterator it1=s.lower_bound(l);
if (it1==s.end())
break;
set<line>::iterator it2=it1;++it2;
if (it2==s.end())
break;
if (it1->b==l.b){
if (it1->a<=l.a){
s.erase(it1);
continue;
}
return;
}
double x=xinter(*it1,*it2);
if (yinter(l,x)<yinter(*it1,x)-eps)
break;
s.erase(it1);
}
while (true){
set<line>::iterator it1=s.upper_bound(l);
if (it1==s.begin())
break;
--it1;
if (it1==s.begin())
break;
set<line>::iterator it2=it1;--it2;
if (it1->b==l.b){
if (it1->a<=l.a){
s.erase(it1);
continue;
}
return;
}
double x=xinter(*it1,*it2);
if (yinter(l,x)<yinter(*it1,x)-eps)
break;
s.erase(it1);
}
set<line>::iterator it1=s.lower_bound(l);
if (it1!=s.end() && it1!=s.begin()){
set<line>::iterator it2=it1;--it2;
double x=xinter(*it1,*it2);
if (yinter(l,x)<=yinter(*it1,x)+eps)
return;
}
s.insert(l);
if (s.size()==1){
last_line=l;
last_x=-1e12;
}
else if (s.find(last_line)==s.end())
last_line=l;
else if (yinter(last_line,last_x)<yinter(l,last_x))
last_line=l;
}
int main(void)
{
int i, x;
freopen("euro.in", "r", stdin);
freopen("euro.out", "w", stdout);
scanf("%d %d", &N, &T);
for (i = 1, S[0] = 0; i <= N; i++)
{
scanf("%d", &x);
S[i] = x + S[i-1];
}
insereaza(line(0, 0));
for (i = 1; i <= N; i++)
{
M[i] = S[i] * i - T + (long long)best(i);
insereaza(line(M[i], -S[i]));
}
printf("%lld\n", M[N]);
return 0;
}