Pagini recente » Cod sursa (job #1659884) | Cod sursa (job #2644402) | Cod sursa (job #763031) | Cod sursa (job #1961287) | Cod sursa (job #1307470)
#include<cstdio>
#include<vector>
#include<set>
using namespace std;
int N, T, S[40000], a[40000];
long long dp[40000];
vector < pair < double, double > > sir;
double eps = 1e-6;
double oo = 1e15;
double Query_A = 1e17;
double mod (double x)
{
if (x < 0) return -x;
return x;
}
class line
{
public:
double A, B;
mutable double x;
line (double A, double B)
{
this->A = A;
this->B = B;
this->x = oo;
}
double val (double x) const
{
return (double) A * x + B;
}
bool operator < (const line &other) const
{
if ( mod (other.A - Query_A) < eps )
return x < other.B;
if ( mod (other.A - A) < eps)
return B > other.B;
return A < other.A;
}
};
class Batch : public multiset < line >
{
public:
void Insert (line curr)
{
iterator it = insert (curr);
if (Bad (it))
{
erase (it);
return ;
}
while (it != begin() && Bad (prev (it)))
erase (prev (it));
while (next (it) != end() && Bad (next (it)))
erase (next (it));
Refresh (it);
if (it != begin()) Refresh (prev(it));
}
double Query (double X)
{
return lower_bound ( line (Query_A, X) ) -> val (X);
}
private:
iterator next (iterator x)
{
iterator y = x;
y ++;
return y;
}
iterator prev (iterator x)
{
iterator y = x;
y --;
return y;
}
bool Bad (iterator y)
{
if (y == end())
return 0;
iterator z = next (y);
if (y == begin())
{
if (z == end())
return 0;
return mod (y->A - z->A) < eps && y->B - z->B < eps;
}
iterator x = prev (y);
if (z == end())
return mod (y->A - x->A) < eps && y->B - x->B < eps;
return (y->B - x->B) * (y->A - z->A) - (z->B - y->B) * (x->A - y->A) > -eps;
}
void Refresh (iterator x)
{
if (x == end())
return ;
iterator y = next (x);
if (y == end())
x->x = oo;
else
x->x = (y->B - x->B) / (x->A - y->A);
}
}smen;
long long get_integer (double x)
{
return (long long) ( (double) x + 0.5 );
}
void brut_insert (pair < double, double > X)
{
sir.push_back (X);
}
double brut_query (double x)
{
double maxx = -oo;
for (vector < pair < double , double > > :: iterator it = sir.begin(); it != sir.end(); it ++)
if ( (double) x * it->first + it->second > maxx)
maxx = (double) x * it->first + it->second;
return maxx;
}
int main()
{
freopen ("euro.in", "r", stdin);
freopen ("euro.out", "w", stdout);
scanf ("%d %d", &N, &T);
for (int i=1; i<=N; i++)
{
scanf ("%d", &a[i]);
S[i] = S[i-1] + a[i];
}
smen.Insert (line (0, 0));
for (int i=1; i<=N; i++)
{
dp[i] = (long long) get_integer (smen.Query (i)) + 1LL * i * S[i] - T;
smen.Insert (line (-S[i], dp[i]));
}
printf ("%lld\n", dp[N]);
return 0;
}