# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
965359 | MisterReaper | Harbingers (CEOI09_harbingers) | C++17 | 65 ms | 25804 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using i64 = long long;
constexpr int maxN = 1E5 + 5;
constexpr i64 INF = 1E18;
int N;
std::vector<std::pair<int, int>> adj[maxN];
int S[maxN], V[maxN], par[maxN], D[maxN];
i64 dp[maxN];
struct line {
i64 a, b;
line(i64 _a, i64 _b) : a(_a), b(_b) {}
i64 eval(i64 x) {
return 1LL * a * x + b;
}
long double intersect(line rhs) {
assert(a != rhs.a);
return (b - rhs.b) / (rhs.a - a);
}
};
std::ostream& operator<< (std::ostream& os, line l) {
return os << '(' << l.a << "x + " << l.b << ')';
}
struct CHTrick {
std::deque<int> before;
std::deque<line> dq;
std::deque<line> rem;
CHTrick() {}
int size() { return (int) dq.size(); }
i64 query(i64 x) {
int l = 0, r = size() - 1;
while(r - l > 3) {
int m = (l + r) >> 1;
if(dq[m].eval(x) >= dq[m + 1].eval(x)) {
l = m;
} else {
r = m;
}
}
i64 res = INF;
for(int i = l; i <= r; i++) {
res = std::min(res, dq[i].eval(x));
}
return res;
}
void add(line l) {
before.emplace_back(size());
while(size() >= 2 && l.intersect(dq[0]) <= dq[0].intersect(dq[1])) {
rem.push_back(dq[0]);
dq.pop_front();
}
dq.push_front(l);
}
void rollback() {
dq.pop_front();
std::deque<line> save;
while((int) save.size() + size() != before.back()) {
save.push_front(rem.back());
rem.pop_front();
}
while(!save.empty()) {
dq.push_front(save.back());
save.pop_back();
}
before.pop_back();
}
} CHT;
std::ostream& operator<< (std::ostream& os, CHTrick w) {
os << '{';
for(int i = 0; i < w.size(); i++) {
if(i != 0) {
os << ", ";
}
os << w.dq[i];
}
return os << '}';
}
void dfs(int v) {
// std::cerr << "vertex: " << v << '\n';
if(v != 1) {
dp[v] = CHT.query(V[v]) + 1LL * D[v] * V[v] + S[v];
}
CHT.add({-D[v], dp[v]});
// std::cerr << v << ' ' << CHT << '\n';
for(auto [u, w] : adj[v]) {
if(u == par[v]) {
continue;
}
D[u] = D[v] + w;
par[u] = v;
dfs(u);
// std::cerr << v << ' ' << CHT << '\n';
}
// std::cerr << v << " roll\n";
CHT.rollback();
// std::cerr << CHT << '\n';
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> N;
for(int i = 1; i <= N - 1; i++) {
int A, B, W;
std::cin >> A >> B >> W;
adj[A].emplace_back(B, W);
adj[B].emplace_back(A, W);
}
for(int i = 2; i <= N; i++) {
std::cin >> S[i] >> V[i];
}
std::fill_n(&dp[1], N, INF);
dp[1] = 0;
par[1] = 1;
dfs(1);
for(int i = 2; i <= N; i++) {
std::cout << dp[i] << " \n"[i == N];
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |