Submission #847012

#TimeUsernameProblemLanguageResultExecution timeMemory
847012Shreyan_PaliwalHarbingers (CEOI09_harbingers)C++17
0 / 100
47 ms65536 KiB
// #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;

template<typename T>
string tostr(const T& value) {
    ostringstream oss;
    oss << fixed << setprecision(7);
    oss << value;
    return oss.str();
}

template<typename... Args>
string fstr(const string& format, Args... args) {
    string result = format;
    size_t pos = 0;
    size_t argIndex = 0;

    auto replaceArg = [&](const auto& arg) {
        pos = result.find("{}", pos);
        if (pos != string::npos) {
            result.replace(pos, 2, tostr(arg));
            ++argIndex;
        }
    };

    (replaceArg(args), ...);

    return result;
}

#define int long long
const int INF = LLONG_MAX / 2 - INT_MAX;
const int INFmem = 0x3f3f3f3f'3f3f3f3f;
const int inf = INT_MAX / 2;
const int infmem = 0x3f3f3f3f;
const int MOD = 1e9 + 7;

#define inp(a, m) {for (int _ = 0; _ < (m); _++) cin >> a[_];}
#define INP(a, m, k) {for (int _ = k; _ < (m)+k; _++) cin >> a[_];}
#define opt(a, m) {for (int _ = 0; _ < (m); _++) cout << a[_] << ' '; cout << endl;}
#define OPT(a, m) {for (int _ = 0; _ < (m); _++) cout << a[_] << '\n'; }

template<int SZ> struct Tree {
    vector<pair<int,int>> adj[SZ];
    void init(int n) {
        for (int i = 0; i < n-1; i++) {
            int a, b, c; cin >> a >> b >> c; a--, b--;
            adj[a].push_back({b,c});
            adj[b].push_back({a,c});
        }
    }
};

#define f first
#define s second

struct F {
    int a, b;
    F() {}
    F(int A, int B) : a(A), b(B) { if (b<0) a*=-1, b*=-1; }
    bool operator<(F o) const { return a*o.b < b*o.a; }
    bool operator<=(F o) const { return a*o.b <= b*o.a; }
};
struct L {
    int m, b;
    int operator()(int x) { return m*x + b; }
    F operator^(L o) { return F{b-o.b,o.m-m}; }
};
struct ND {
    L v;
    ND *l, *r;

    ND(int m, int b) { v = L{m, b}; l = r = nullptr; }
    ND(ND* _l, ND* _r) { v = L{0, 0}; _l = _r = nullptr; }
};

struct Node {
    L v;
    Node *l, *r;
    Node(L x) : v(x), l(nullptr), r(nullptr) {}
    Node(Node* _l, Node* _r) : l(_l), r(_r) { v = L{0ll, 0ll}; }
};

const int maxn = 100005;

int n;
Tree<maxn> tree;
pair<int,int> v[maxn];
int dist[maxn];
int st[maxn];
int ans[maxn];

template<int SZ> struct PersArray {
    Node* roots[SZ];
    int end[SZ];
    Node* build(int l, int r) {
        if (l == r) { return new Node(L{0ll, 0ll}); }
        int m = (l + r) >> 1;
        return new Node(build(l, m), build(m+1, r));
    }
    void init() { roots[0] = build(0, n-1); }
    Node* UPD(Node* nd, int K, L V, int l, int r) {
        if (l == r) { return new Node(V); }
        int m = (l + r) >> 1;
        if (K <= m) return new Node(UPD(nd->l, K, V, l, m), nd->r);
        else return new Node(nd->l, UPD(nd->r, K, V, m+1, r));
    }
    L QRY(Node* nd, int K, int l, int r) {
        if (l == r) return nd->v;
        int m = (l + r) >> 1;
        if (K <= m) return QRY(nd->l, K, l, m);
        else return QRY(nd->r, K, m+1, r);
        return L{0ll, 0ll};
    }
    inline L qry(int K, int T) {
        return QRY(roots[T], K, 0, n-1);
    }
    inline void upd(int K, L V, int T, int Tp) {
        roots[T] = UPD(roots[Tp], K, V, 0, n-1);
    }
};

struct CHT {
    // MAKE SURE TO UPDATE < OR > FOR MIN/MAX QUERY
    // vector<L> h;
    // deque<L> h; 
    PersArray<maxn> pers;
    void add(int nd, int par, L l) {
        // min hull + decreasing slopes OR max hull + increasing slopes
        int sz = pers.end[par];
        while (sz >= 2 && (pers.qry(sz-2,par) ^ l) <= (pers.qry(sz-2,par) ^ pers.qry(sz-1, par)))
            sz--;
        pers.upd(sz, l, nd, par);
        pers.end[nd] = sz + 1;

        // // min hull + increasing slopes OR max hull + decreasing slopes
        // while (h.size() >= 2 && (h.end()[-2]^h.back()) <= (h.end()[-2]^l)) h.pop_back();
        // h.push_back(l);
    }
    int qry(int nd, int x) {
        // O(N log N) time, unordered queries
        // USE VECTOR
        int lo = 0, hi = pers.end[nd]-1;
        // cout << nd << endl;
        // for (int i = 0; i < pers.end[nd]; i++){
        //     L x = (pers.qry(i, nd)); cout << x.m << ' ' << x.b << endl;}
        // cout << "END" << endl;
        while (lo < hi) {
            int m = (lo + hi) >> 1;
            if (pers.qry(m, nd)(x) > pers.qry(m+1, nd)(x))
                lo = m+1;
            else 
                hi = m;
        }
        return (pers.qry(lo, nd))(x);
    }
};

CHT cht;

int cnt = 0;
void dfs(int nd, int par) {
    st[nd] = cnt++;

    // if (nd != 0)
    //     cout << "----------" << endl << "ND " << nd << ' ';
    if (nd != 0)
        ans[nd] =  v[nd].f + v[nd].s * dist[nd] + cht.qry(st[par], v[nd].s);
    // if (nd != 0)
    //     cout << ans[nd] << endl;

    cht.add(st[nd], st[par], L{-dist[nd], ans[nd]});

    for (auto i : tree.adj[nd])
        if (i.f != par) {
            dist[i.f] = dist[nd] + i.s;
            dfs(i.f, nd);
        }

}

void solve() {
    cin >> n;
    tree.init(n);
    for (int i = 1; i < n; i++) cin >> v[i].f >> v[i].s;

    cht.pers.init();

    dfs(0, 0);

    for (int i = 1; i < n; i++)
        cout << ans[i] << ' ';
    cout << endl;
}

// #define LOCAL
// #define CODEFORCES
signed main() {
    #ifndef LOCAL
    cin.tie(nullptr) -> ios::sync_with_stdio(false);
    freopen("harbringers.in", "r", stdin);
    freopen("harbrings.out", "w", stdout);
    #endif
    #ifdef LOCAL
    freopen("main.in", "r", stdin);
    #endif
    int t; 
    #ifdef CODEFORCES
    cin >> t;
    #endif
    #ifndef CODEFORCES
    t=1;
    #endif
    for (int i = 1; i <= t; i++) {
        #ifdef LOCAL
        cout << fstr("----- Case {} -----", i) << endl;
        auto startTime = clock();
        #endif 
        solve();
        #ifdef LOCAL
        cout << fstr("RUNTIME: {}", (double)(clock() - startTime)/CLOCKS_PER_SEC) << endl;
        cout << fstr("----- END CASE {} -----", i) << endl;
        #endif
        #ifdef LOCAL
        #endif
    }
    return 0;
}

Compilation message (stderr)

harbingers.cpp: In function 'int main()':
harbingers.cpp:202:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  202 |     freopen("harbringers.in", "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
harbingers.cpp:203:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  203 |     freopen("harbrings.out", "w", stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...