답안 #847192

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
847192 2023-09-09T09:21:21 Z Shreyan_Paliwal Harbingers (CEOI09_harbingers) C++17
80 / 100
147 ms 22864 KB
// // #pragma GCC optimize("Ofast")
// #include <bits/stdc++.h>
// using namespace std;

// 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

// const int maxn = 100005;

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

// 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}; }
// };
// 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 {
//     PersArray<maxn> pers;
//     void add(int nd, int par, L l) {
//         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;
//     }
//     int qry(int nd, int x) {
//         int lo = 0, hi = pers.end[nd]-1;
//         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, int parst) {
//     int cur = cnt++;

//     if (nd != 0)
//         ans[nd] =  v[nd].f + v[nd].s * dist[nd] + cht.qry(parst, v[nd].s);

//     cht.add(cur, parst, 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, cur);
//         }

// }

// signed main() {
//     cin.tie(nullptr) -> ios::sync_with_stdio(false);
//     // freopen("main.in", "r", stdin);

//     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, 0);

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

//     return 0;
// }

/************ PERSISTANT ARRAY ALGO ABOVE, EXCEEDS TIME DUE TO CONSTANTS AND ALSO MEMORY **************/
/************ CHT ALGO BELOW, PASSES **************/

// #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

#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}; }
};

const int maxn = 100000;
int n;
vector<pair<int,int>> adj[maxn];
pair<int,int> v[maxn];

pair<int,L> removed[maxn];

int ans[maxn];

L CHT[maxn]; int cht_sz = 0;
void add(L l, int nd) {
    if (!cht_sz) { CHT[cht_sz++] = l; return; }
    removed[nd] = {cht_sz, l};
    int hi = cht_sz; cht_sz = 1;  // represents range for new one
    while (cht_sz < hi) {
        int mid = (cht_sz + hi) >> 1; // will test MID & (MID+1)
        if ((CHT[mid-1]^l) <= (CHT[mid-1]^CHT[mid]))
            hi = mid;
        else 
            cht_sz = mid+1;
    }
    swap(removed[nd].s, CHT[cht_sz++]);
}
int qry(int x) {
    int lo = 0, hi = cht_sz-1;
    while (lo < hi) {
        int m = (lo + hi) >> 1;
        if (CHT[m](x) > CHT[m+1](x)) 
            lo = m+1;
        else 
            hi = m;
    }
    return CHT[lo](x);
}
void restore(int nd) {
    cht_sz--;
    swap(removed[nd].s, CHT[cht_sz]);
    cht_sz = removed[nd].f;
}

void dfs(int nd, int par, int d) {
    add(L{-d, ans[nd]}, par);


    for (auto i : adj[nd])
        if (i.f != par) {
            ans[i.f] = v[i.f].f + v[i.f].s * (d + i.s) + qry(v[i.f].s);
            dfs(i.f, nd, d + i.s);
        }
    restore(par);
}

signed main() {
    // freopen("main.in", "r", stdin);

    cin >> 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});
    }
    for (int i = 1; i < n; i++) cin >> v[i].f >> v[i].s;

    dfs(0, 0, 0);

    for (int i = 1; i < n; i++) cout << ans[i] << ' '; 
    cout << endl;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 6744 KB Output is correct
2 Correct 4 ms 7260 KB Output is correct
3 Incorrect 56 ms 13392 KB Output isn't correct
4 Correct 82 ms 16916 KB Output is correct
5 Correct 102 ms 19896 KB Output is correct
6 Correct 128 ms 22864 KB Output is correct
7 Correct 77 ms 13856 KB Output is correct
8 Incorrect 143 ms 18372 KB Output isn't correct
9 Correct 147 ms 20320 KB Output is correct
10 Correct 118 ms 18632 KB Output is correct