Submission #237138

# Submission time Handle Problem Language Result Execution time Memory
237138 2020-06-04T19:00:54 Z xiaowuc1 Harbingers (CEOI09_harbingers) C++14
50 / 100
135 ms 23288 KB
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <vector>

using namespace std;

// BEGIN NO SAD
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
typedef vector<int> vi;
// END NO SAD

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<vector<ll>> matrix;
typedef pair<ll, ll> pll;

struct Line {
	mutable ll k, m, p;
	bool operator<(const Line& o) const { return k < o.k; }
	bool operator<(ll x) const { return p < x; }
};

struct LineContainer : multiset<Line, less<>> {
	// (for doubles, use inf = 1/.0, div(a,b) = a/b)
	const ll inf = 1LL << 62;
	ll div(ll a, ll b) { // floored division
		return a / b - ((a ^ b) < 0 && a % b); }
	bool isect(iterator x, iterator y) {
		if (y == end()) { x->p = inf; return false; }
		if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
		else x->p = div(y->m - x->m, x->k - y->k);
		return x->p >= y->p;
	}
	void add(ll k, ll m) {
    k *= -1;
    m *= -1;
		auto z = insert({k, m, 0}), y = z++, x = y;
		while (isect(y, z)) z = erase(z);
		if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
		while ((y = x) != begin() && (--x)->p >= y->p)
			isect(x, erase(y));
	}
	ll query(ll x) {
		assert(!empty());
		auto l = *lower_bound(x);
    ll val = -(l.k * x + l.m);
		return val;
	}
};

int n;
vector<pii> edges[100005];
ll ret[100005];
ll dist[100005];
ll gain[100005];
ll timeper[100005];
LineContainer lc;
void dfs(int curr, int par) {
  if(curr > 1) {
    ret[curr] = gain[curr] + timeper[curr]*dist[curr] + lc.query(timeper[curr]);
  }
  for(pii out: edges[curr]) {
    if(out.first == par) continue;
    lc.add(-dist[curr], ret[curr]);
    dist[out.first] = dist[curr] + out.second;
    dfs(out.first, curr);
    Line l;
    l.k = dist[curr];
    l.m = -ret[curr];
    l.p = -(1LL << 62);
    auto it = lc.lower_bound(l);
    if(it == lc.end()) {
      continue;
    }
    Line q = *it;
    if(l.k != q.k) {
      continue;
    }
    if(l.m != q.m) {
      continue;
    }
    lc.erase(it);
  }
}

void solve() {
  cin >> n;
  for(int i = 1; i < n; i++) {
    int a, b, w;
    cin >> a >> b >> w;
    edges[a].emplace_back(b, w);
    edges[b].emplace_back(a, w);
  }
  for(int i = 2; i <= n; i++) cin >> gain[i] >> timeper[i];
  dfs(1, -1);
  for(int i = 2; i <= n; i++) cout << ret[i] << " \n"[i == n];
}

// are there edge cases (N=1?)
// are array sizes proper (scaled by proper constant, for example 2* for koosaga tree)
// integer overflow?
// DS reset properly between test cases

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL); cout.tie(NULL);
  solve();
}
# Verdict Execution time Memory Grader output
1 Incorrect 7 ms 2688 KB Output isn't correct
2 Correct 8 ms 3200 KB Output is correct
3 Correct 58 ms 11988 KB Output is correct
4 Correct 82 ms 16504 KB Output is correct
5 Correct 102 ms 19484 KB Output is correct
6 Correct 135 ms 23288 KB Output is correct
7 Incorrect 74 ms 12664 KB Output isn't correct
8 Incorrect 133 ms 19964 KB Output isn't correct
9 Incorrect 129 ms 20344 KB Output isn't correct
10 Incorrect 128 ms 21148 KB Output isn't correct