Submission #1036524

#TimeUsernameProblemLanguageResultExecution timeMemory
1036524model_codePetrol stations (CEOI24_stations)C++17
100 / 100
2103 ms1082960 KiB
// Author: Pepa Minařík
#include <bits/stdc++.h>

using namespace std;

#define ll long long

int n;
ll k;

struct tree {
    int sum = 0;
    tree *left_child = nullptr, *right_child = nullptr;

    void extend(ll left, ll right) {
        if (!left_child && left + 1 < right) {
            left_child = new tree();
            right_child = new tree();
        }
    }

	void add(ll kk, ll x, ll left = 0, ll right = (n + 1) * k)
	{
        sum += x;
        if (left + 1 < right) {
            if (kk < (left + right) / 2)
			{
				if (!left_child) left_child = new tree();
                left_child->add(kk, x, left, (left + right) / 2);
			}
            else
			{
				if (!right_child) right_child = new tree();
                right_child->add(kk, x, (left + right) / 2, right);
			}
        }
	}

	int get_sum(ll lq, ll rq, ll left = 0, ll right = (n + 1) * k) {
        if (lq <= left && right <= rq)
            return sum;
        if (max(left, lq) >= min(right, rq))
            return 0;
		ll answer = 0;
		if (left_child)
			answer += left_child->get_sum(lq, rq, left, (left + right) / 2);
		if (right_child)
			answer += right_child->get_sum(lq, rq, (left + right) / 2, right);
        return answer;
    }
};


ll ans[100005];
bool blocked[100005];
int depth[100005], siz[100005], keys[100005], multiplicity[100005];
int pred[100005][20];
ll dist[100005][20];
vector<pair<int, int>> graf[100005];
map<int, vector<pair<int, int>>> key_to_cars[100005];

void stage_up(int v, int f, int d, int l, int key)
{
	depth[v] = d;
	pred[v][0] = f;
	dist[v][0] = l;
	keys[v] = key;
	siz[v] = multiplicity[v] = 1;
	for (int i = 1; i < 20; i++)
	{
		pred[v][i] = pred[pred[v][i-1]][i-1];
		dist[v][i] = dist[v][i-1] + dist[pred[v][i-1]][i-1];
	}
	for (auto u : graf[v])
	{
		if (u.first == f || blocked[u.first]) continue;
		int new_key = key;
		if (d == 0)
			new_key = u.first;
		stage_up(u.first, v, d+1, u.second, new_key);
		siz[v] += siz[u.first];
	}

	int u = v;
	ll dist_from_v = 0;
	for (int i = 19; i >= 0; i--)
	{
		if (dist_from_v + dist[u][i] <= k)
		{
			dist_from_v += dist[u][i];
			u = pred[u][i];
		}
	}
	if (depth[u])
		multiplicity[u] += multiplicity[v];
	else
        key_to_cars[u][keys[v]].push_back({k - dist_from_v, multiplicity[v]});
}

void stage_down(int v, int f, ll dist_from_root, tree *t, int total_size, int key_size)
{
	ans[v] += (multiplicity[v] - 1) * (ll)(total_size - key_size);
	for (auto u : graf[v])
	{
		if (u.first == f || blocked[u.first]) continue;
		if (!dist_from_root)
			for (auto car: key_to_cars[v][keys[u.first]])
				t->add(car.first, -car.second);	
		ll multiplicity_to_add = t->get_sum(dist_from_root, dist_from_root + u.second);
		ans[v] += multiplicity_to_add * (ll)siz[u.first];
        t->add(dist_from_root + k, multiplicity_to_add);
		int new_key_size = depth[v] ? key_size : siz[u.first];
		stage_down(u.first, v, dist_from_root + u.second, t, total_size, new_key_size);
        t->add(dist_from_root + k, -multiplicity_to_add);
		if (!dist_from_root)
			for (auto car: key_to_cars[v][keys[u.first]])
				t->add(car.first, car.second);	
	}
}


int find_centroid(int v, int f, int s)
{
	for (auto u : graf[v])
	{
		if (u.first == f || blocked[u.first]) continue;
		if (siz[u.first] > s/2)
			return find_centroid(u.first, v, s);
	}
	return v;
}

void solve(int v)
{
	stage_up(v, v, 0, 0, -1);
    tree *t = new tree();
	for (auto pair: key_to_cars[v])
		for (auto car : pair.second)
			t->add(car.first, car.second);

	stage_down(v, v, 0, t, siz[v], 0);

	blocked[v] = true;
	for (auto u : graf[v])
	{
		if (blocked[u.first]) continue;
		int c = find_centroid(u.first, v, siz[u.first]);
		solve(c);
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> k;
	int u, v, l;
	for (int i = 0; i < n-1; i++)
	{
		cin >> u >> v >> l;
		graf[u].push_back({v, l});
		graf[v].push_back({u, l});
	}
	solve(0);

	for (int i = 0; i < n; i++)
		cout << ans[i] << "\n";	
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...