Cod sursa(job #1458190)

Utilizator jcg9129Jose Carlos Gutierrez Perez jcg9129 Data 7 iulie 2015 04:50:35
Problema Euro Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <bits/stdc++.h>
#include <ext/algorithm>
#include <ext/numeric>

using namespace std;
using namespace __gnu_cxx;

#define endl '\n'

typedef long long i64;

const i64 oo = 0x3f3f3f3f3f3f3f3f;

// upper hull
struct convex_hull_trick
{
	convex_hull_trick(int sz = 50) : h(sz) { }

	void add(i64 a, i64 b)
	{
	    hull cur = hull(a, b);
	    int i;
	    for (i = 1; !h[i].isEmpty(); ++i)
	    {
	        cur = merge(cur, h[i]);
	        h[i].setEmpty();
	    }

	    h[i] = cur;
	}

	i64 get_max(i64 x)
	{
	    i64 ans = -oo;

	    for (int i = 1; i < h.size(); ++i)
	    	if (!h[i].isEmpty())
	            ans = max(ans, h[i].get(x));

	    return ans;
	}

private:
	struct hull
	{
	    vector< pair<i64,i64> > v;

	    hull() {}

	    hull(i64 a, i64 b)
	    {
	        v.clear();
	        v.push_back(make_pair(a, b));
	    }

	    void add(i64 a, i64 b)
	    {
	        while (v.size() >= 1 && v.back().first == a && v.back().second < b)
	            v.pop_back();

	        if (!v.empty() && v.back().first == a)
	            return;

	        while (v.size() >= 2)
	        {
	            i64 a1, a2, b1, b2;
	            a1 = v[(int)v.size() - 2].first;
	            a2 = v[(int)v.size() - 1].first;
	            b1 = v[(int)v.size() - 2].second;
	            b2 = v[(int)v.size() - 1].second;

	            if ((b1 - b2) * (a - a1) > (b1 - b) * (a2 - a1))
	                v.pop_back();
	            else
	                break;
	        }

	        v.push_back(make_pair(a, b));
	    }

	    bool isEmpty() { return v.empty(); }

	    void setEmpty() { v.clear(); }

	    i64 get(i64 x)
	    {
	        int lo = 0, hi = (int)v.size() - 1;

	        while (lo < hi)
	        {
	            int mid = (lo + hi) >> 1;

	            if (f(v[mid].first, v[mid].second, x) <= 
	                    f(v[mid + 1].first, v[mid + 1].second, x))
	                lo = mid + 1;
	            else
	                hi = mid;
	        }

	        return f(v[lo].first, v[lo].second, x);
	    }

	    i64 f(i64 a, i64 b, i64 x)
	    {
	        return a * x + b;
	    }
	};

	hull merge(const hull &a, const hull &b)
	{
	    int i, j;
	    i = j = 0;
	    
	    hull ans;

	    while (i < a.v.size() && j < b.v.size())
	    {
	        if (a.v[i].first < b.v[j].first)
	            ans.add(a.v[i].first, a.v[i].second), ++i;
	        else
	            ans.add(b.v[j].first, b.v[j].second), ++j;
	    }

	    while (i < a.v.size()) 
	    	ans.add(a.v[i].first, a.v[i].second), ++i;
	    while (j < b.v.size()) 
	    	ans.add(b.v[j].first, b.v[j].second), ++j;

	    return ans;
	}

	vector<hull> h;
};

int main()
{
	freopen("euro.in", "r", stdin);
	freopen("euro.out", "w", stdout);
	
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n, t;
	cin >> n >> t;

	convex_hull_trick hull;
	hull.add(0, 0);

	i64 sum = 0, dp = 0;
	for (int i = 1; i <= n; ++i)
	{
		i64 s;
		cin >> s;
		sum += s;

		dp = hull.get_max(i) + sum * i - t;
		hull.add(-sum, dp);
	}

	cout << dp << endl;
	
	return 0;
}