Cod sursa(job #2610047)

Utilizator trifangrobertRobert Trifan trifangrobert Data 4 mai 2020 01:48:13
Problema Euro Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 35000;
int N;
long long T, sum[NMAX], dp[NMAX];
long long dp2[NMAX];

struct LiChao
{
    long long m, n;
};

LiChao cht[4 * NMAX];

int LeftSon(int node)
{
    return 2 * node;
}

int RightSon(int node)
{
    return 2 * node + 1;
}

void AddLine(int node, int left, int right, LiChao line)
{
    if (left == right)
    {
        if (cht[node].m * left + cht[node].n < line.m * left + line.n)
            cht[node] = line;
        return;
    }
    int mid = (left + right) / 2;
    int valmid = ((cht[node].m * mid + cht[node].n) < (line.m * mid + line.n));
    int valleft = ((cht[node].m * left + cht[node].n) < (line.m * left + line.n));
    if (valleft == 0 && valmid == 0)
        AddLine(RightSon(node), mid + 1, right, line);
    else if (valleft == 1 && valmid == 0)
        AddLine(LeftSon(node), left, mid, line);
    else if (valleft == 0 && valmid == 1)
    {
        swap(line, cht[node]);
        AddLine(LeftSon(node), left, mid, line);
    }
    else
    {
        swap(line, cht[node]);
        AddLine(RightSon(node), mid + 1, right, line);
    }
}

long long Query(int node, int left, int right, int x)
{
    if (left == right)
        return 1LL * cht[node].m * x + cht[node].n;
    int mid = (left + right) / 2;
    if (x <= mid)
        return max(1LL * cht[node].m * x + cht[node].n, Query(LeftSon(node), left, mid, x));
    else
        return max(1LL * cht[node].m * x + cht[node].n, Query(RightSon(node), mid + 1, right, x));
}

int main()
{
    ifstream fin("euro.in");
    ofstream fout("euro.out");
    fin >> N >> T;
    for (int i = 1;i <= N;++i)
    {
        fin >> sum[i];
        sum[i] += sum[i - 1];
    }
    for (int i = 1;i <= N;++i)
    {
        dp[i] = 1LL * sum[i] * i - T + Query(1, 1, N, i);
        AddLine(1, 1, N, {-sum[i], dp[i]});
    }
    fout << dp[N] << "\n";
    fin.close();
    fout.close();
    return 0;
}