Submission #395025

#TimeUsernameProblemLanguageResultExecution timeMemory
395025ocarimaHarbingers (CEOI09_harbingers)C++14
60 / 100
1085 ms34160 KiB
#include<bits/stdc++.h>

using namespace std;

#define lli long long
#define rep(x, a, b) for(lli x = (a); x <= (b); ++x)
#define debugsl(x) cout << #x << " = " << x << "; "
#define debug(x) debugsl(x); cout << endl
#define debugarr(x, a, b) cout << #x << " = ["; rep(ix, a, b) cout << x[ix] << ", "; cout << "]" << endl
#define nl "\n"

#define MAX_N 100003
#define INF (1 << 50)
#define in cin
#define out cout

#define ciudad first
#define distancia second

double pre[MAX_N], sig[MAX_N];

struct rec{
    int ind;
    bool operator<(const rec& a) const{
        if (pre[ind] == pre[a.ind]) return sig[ind] < sig[a.ind];
        else return pre[ind] < pre[a.ind];
    }

    rec(int x)
        : ind(x){};
};

lli n, a, b, d, v[MAX_N], s[MAX_N], pos[MAX_N], dp[MAX_N];
vector<pair<lli, lli> > hijos[MAX_N];
set<rec> ch;
bool buscapunto;

#define eval(r, p) ((-pos[r])*p + dp[r])
#define cruce(r1, r2) ((dp[r2] - dp[r1] + 0.0) / (pos[r2] - pos[r1] + 0.0))

lli optimoch(lli nodo){
    pre[n + 1] = v[nodo];
    auto it = (--ch.upper_bound({n + 1}));
    return eval((*it).ind, v[nodo]);
}

void dfs(lli nodo, lli padre, lli posicion){

    set<rec> tmp;
    lli r;

    pos[nodo] = posicion; // ASIGNALE SU POSICION

    // CALCULA EL OPTIMO PARA ESTE NODO
    dp[nodo] = optimoch(nodo) + s[nodo] + (v[nodo] * pos[nodo]);

    // METE SU LINEA AL CONVEX HULL
    // LAS LINEAS VAN AL FINAL
    auto it = (--ch.end());
    while (nodo != 1 && !ch.empty() && pre[(*it).ind] > cruce((*it).ind, nodo)){
        tmp.emplace_hint(tmp.begin(), (*it)); // GUARDA LOS QUE ELIMINAS PARA DESPUES VOLVERLOS A INSERTAR Y QUE QUEDE IGUAL
        ch.erase(next(--it));
    }

    if (nodo != 1 && !ch.empty()){
        it = (--ch.end());

        r = (*it).ind;
        pre[nodo] = sig[r] = cruce(r, nodo);
        sig[nodo] = INF;

        ch.emplace_hint(ch.end(), nodo);
    }

    // BAJA A SUS HIJOS
    for (auto h : hijos[nodo]){
        if (h.ciudad == padre) continue;
        dfs(h.ciudad, nodo, posicion + h.distancia);
    }

    // ELIMINA SU LINEA DEL CONVEX HULL
    it = (--ch.end());
    if (nodo != 1 && (*it).ind == nodo){
        ch.erase(it);
        it = (--ch.end());

        r = (*it).ind;

        if (tmp.empty()) sig[r] = INF;
        else{
            sig[r] = pre[(*tmp.begin()).ind];
            for (auto r : tmp) ch.emplace_hint(ch.end(), r);
            tmp.clear();
        }
    }
}

int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0);

    in >> n;
    rep(i, 1, n - 1){
        in >> a >> b >> d;
        hijos[a].emplace_back(b, d);
        hijos[b].emplace_back(a, d);
    }
    rep(i, 2, n) in >> s[i] >> v[i];

    sig[1] = INF;
    ch.emplace_hint(ch.end(), 1);

    dfs(1, 0, 0);

    rep(i, 2, n) out << dp[i] << " ";

    return 0;
}

Compilation message (stderr)

harbingers.cpp: In function 'long long int optimoch(long long int)':
harbingers.cpp:43:36: warning: narrowing conversion of '(n + 1)' from 'long long int' to 'int' [-Wnarrowing]
   43 |     auto it = (--ch.upper_bound({n + 1}));
      |                                  ~~^~~
harbingers.cpp: In function 'void dfs(long long int, long long int, long long int)':
harbingers.cpp:13:19: warning: left shift count >= width of type [-Wshift-count-overflow]
   13 | #define INF (1 << 50)
      |                   ^~
harbingers.cpp:70:21: note: in expansion of macro 'INF'
   70 |         sig[nodo] = INF;
      |                     ^~~
harbingers.cpp:13:19: warning: left shift count >= width of type [-Wshift-count-overflow]
   13 | #define INF (1 << 50)
      |                   ^~
harbingers.cpp:89:35: note: in expansion of macro 'INF'
   89 |         if (tmp.empty()) sig[r] = INF;
      |                                   ^~~
harbingers.cpp: In function 'int main()':
harbingers.cpp:13:19: warning: left shift count >= width of type [-Wshift-count-overflow]
   13 | #define INF (1 << 50)
      |                   ^~
harbingers.cpp:110:14: note: in expansion of macro 'INF'
  110 |     sig[1] = INF;
      |              ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...