Pagini recente » Cod sursa (job #132063) | Cod sursa (job #2892313) | Cod sursa (job #1475467) | Cod sursa (job #2846411) | Cod sursa (job #2513898)
#include <fstream>
#include <cmath>
#include <stack>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
ifstream fin("euro.in");
ofstream fout("euro.out");
const long long NMax = 34567, oo = LLONG_MAX;
long long N, V[NMax + 5], S[NMax + 5], T, sqrtN, NrBuckets, DP[NMax + 5];
struct bucket
{
vector< pair<long long, long long> > Line;
stack <long long> Hull;
long long Stop[200], low, hi;
}
Bucket[200];
long long Intersect(pair<long long, long long> L1, pair<long long, long long> L2)
{
if(L1.first == L2.first)
return -oo;
return (L1.second - L2.second) / (L2.first - L1.first);
}
inline bool compare(pair<long long, long long> A, pair<long long, long long> B)
{
return A > B;
}
void CreateHull(bucket & B)
{
sort(B.Line.begin(), B.Line.end(), compare);
B.Stop[0] = oo;
B.Hull.push(0);
for(long long i = 1; i < B.Line.size(); i++)
{
while(Intersect(B.Line[B.Hull.top()], B.Line[i]) > B.Stop[B.Hull.top()])
B.Hull.pop();
B.Stop[i] = Intersect(B.Line[B.Hull.top()], B.Line[i]);
B.Hull.push(i);
}
}
long long Query(bucket & B, long long x)
{
while(x > B.Stop[B.Hull.top()])
B.Hull.pop();
pair <long long, long long> line = B.Line[B.Hull.top()];
return line.first * x + line.second;
}
int main()
{
fin >> N >> T;
sqrtN = sqrt(N);
for(long long i = 1; i <= N; i++)
{
fin >> V[i];
S[i] = V[i] + S[i - 1];
/// DP[i] = (-S[j] * i + DP[j] ) + (S[i] * i - T), j < i
for(long long k = 1; k <= NrBuckets; k++)
DP[i] = max(DP[i], Query(Bucket[k], i));
for(auto line : Bucket[NrBuckets + 1].Line)
DP[i] = max(DP[i], line.first * i + line.second);
DP[i] += S[i] * i - T;
Bucket[NrBuckets + 1].Line.push_back({-S[i], DP[i]});
if(i % sqrtN == 0)
{
NrBuckets++;
Bucket[NrBuckets].low = i - sqrtN + 1, Bucket[NrBuckets].hi = i;
CreateHull(Bucket[NrBuckets]);
}
}
fout << DP[N] << '\n';
fin.close();
fout.close();
return 0;
}