Submission #1239879

#TimeUsernameProblemLanguageResultExecution timeMemory
1239879jerzykMeetings (IOI18_meetings)C++20
100 / 100
1633 ms358820 KiB
#include <bits/stdc++.h>
#include "meetings.h"

using namespace std;
#define pb push_back
#define st first
#define nd second
typedef long long ll;
typedef long double ld;
const int II = 2'000'000'000;
const ll I = 1000LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL;
const ll M = 1000LL * 1000LL * 1000LL + 7LL;
const int N = 1<<20;
int tab[N], ed[N][2], ran[N][2];
pair<int, int> rmq[N][20];

pair<int, int> que[N];
vector<int> wh[N];
ll answer[N];
pair<ll, ll> drz[2][2 * N];
ll lazd[2][2 * N];

int GetMax(int a, int b)
{
    int d = b - a + 1;
    int p = 31 - __builtin_clz(d);
    if(rmq[a][p].st >= rmq[b - (1<<p) + 1][p].st)
        return -rmq[a][p].nd;
    return -rmq[b - (1<<p) + 1][p].nd;
}

void Licz(int n)
{
    for(int i = n; i >= 1; --i)
    {
        rmq[i][0] = pair{tab[i], -i};
        for(int j = 1; i + (1<<j) - 1 <= n; ++j)
            rmq[i][j] = max(rmq[i][j - 1], rmq[i + (1<<(j - 1))][j - 1]);
    }
    vector<int> cur;
    tab[0] = II; cur.pb(0);
    for(int i = 1; i <= n; ++i)
    {
        while(tab[cur.back()] < tab[i])
        {
            ed[i][0] = cur.back();
            cur.pop_back();
        }
        ed[cur.back()][1] = i;
        cur.pb(i);
    }
}

inline void Push(int r, int v)
{
    for(int s = v * 2; s <= v * 2 + 1; ++s)
    {
        lazd[r][s] += lazd[r][v];
        drz[r][s].nd += lazd[r][v];
    }
    lazd[r][v] = 0LL;
}

void Add(int r, int v, int p, int k, int pz, int kz, ll x)
{
    if(pz > kz) return;
    if(p > kz || k < pz) return;
    if(p >= pz && k <= kz)
    {
        lazd[r][v] += x;
        drz[r][v].nd += x;
        return;
    }
    Add(r, v * 2, p, (p + k) / 2, pz, kz, x);
    Add(r, v * 2 + 1, (p + k) / 2 + 1, k, pz, kz, x);
}

void Upd(int r, int v, int p, int k, pair<ll, ll> x)
{
    if(v < N) Push(r, v);

    if(x <= drz[r][v])
        swap(x, drz[r][v]);
    ll pos = (p + k) / 2;
    if(x.st * pos + x.nd < drz[r][v].st * pos + drz[r][v].nd)
    {
        swap(drz[r][v], x);
        if(v < N)
            Upd(r, v * 2 + 1, (p + k) / 2 + 1, k, x);
    }else
    {
        if(v < N)
            Upd(r, v * 2, p, (p + k) / 2, x);
    }
}


void Change(int r, int v, int p, int k, int pz, int kz, pair<ll, ll> x)
{
    if(pz > kz) return;
    if(p > kz || k < pz) return;
    if(p >= pz && k <= kz)
    {
        Upd(r, v, p, k, x);
        return;
    }
    Push(r, v);
    Change(r, v * 2, p, (p + k) / 2, pz, kz, x);
    Change(r, v * 2 + 1, (p + k) / 2 + 1, k, pz, kz, x);
}

ll Query(int r, int v)
{
    ll pos = v;
    v += N;
    ll ans = I;
    while(v > 0)
    {
        ans += lazd[r][v];
        ans = min(ans, drz[r][v].st * pos + drz[r][v].nd);
        
        v /= 2;
    }
    return ans;
}

void DFS(int v)
{
    ran[v][0] = v; ran[v][1] = v;
    for(int l = 0; l < 2; ++l)
        if(ed[v][l] != 0)
        {
            DFS(ed[v][l]);
            ran[v][l] = ran[ed[v][l]][l];
        }
    ll val = tab[v];
    // cout << "\nDFS " << v << " | " << ed[v][0] << " " << ed[v][1] << '\n';
    for(int l = 0; l < (int)wh[v].size(); ++l)
    {
        int a = que[wh[v][l]].st, b = que[wh[v][l]].nd;
        ll cur = Query(1, a) + (ll)(b - v + 1) * val;
        ll cur2 = Query(0, b) + (ll)(v - a + 1) * val;
        // cout << "Q: " << wh[v][l] << " " << cur << " " << cur2 << "\n";
        answer[wh[v][l]] = min(cur, cur2);
    }
    Add(0, 1, 0, N - 1, v, ran[v][1], val * (ll)(v - ran[v][0] + 1));
    Add(1, 1, 0, N - 1, ran[v][0], v, val * (ll)(ran[v][1] - v + 1));
    // cout << "XD: " << Query(1, 2) << "\n";
    if(v > ran[v][0])
    {
        ll cur = Query(0, v - 1);
        pair<ll, ll> a = pair{val, cur - (ll)(v - 1) * val};
        Change(0, 1, 0, N - 1, v, ran[v][1], a);
    }

    if(v < ran[v][1])
    {
        ll cur = Query(1, v + 1);
        pair<ll, ll> a = pair{-val, cur + (ll)(v + 1) * val};
        Change(1, 1, 0, N - 1, ran[v][0], v, a);
    }
    // cout << "XD: " << Query(1, 2) << "\n";
}

vector<long long> minimum_costs(vector<int> H, vector<int> L, vector<int> R) 
{
    for(int r = 0; r < 2; ++r)
        for(int i = 1; i < N; ++i)
            drz[r][i] = pair{0LL, I};
    int n = H.size(), q = L.size();
    for(int i = 1; i <= n; ++i) tab[i] = H[i - 1];
    Licz(n);
    for(int i = 1; i <= q; ++i)
    {
        que[i] = pair{L[i - 1] + 1, R[i - 1] + 1};
        int akt = GetMax(que[i].st, que[i].nd);
        wh[akt].pb(i);
    }
    int s = GetMax(1, n);
    
    DFS(s);
    vector<ll> ans;
    for(int i = 1; i <= q; ++i)
        ans.pb(answer[i]);
    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...