Cod sursa(job #3247910)

Utilizator luc3lexaAlexandrescu Luca luc3lexa Data 9 octombrie 2024 19:49:26
Problema Cerere Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.51 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("cerere.in");
ofstream fout("cerere.out");

const int nmax = 1e5+10;
const int LOG_MAX = 20;

int n,root;
vector<int> k_value(nmax,0),parent(nmax,0),topological_order,visited(nmax,0);
vector<int> value(nmax,0);
vector<vector<int>> up(LOG_MAX,vector<int> (nmax,0)),mat(nmax);

void read_input(){
	fin >> n;
	for(int i = 1; i <=n; i++){
		fin >> k_value[i];
	};
	int nod_1,nod_2;
	for(int i = 1; i <=n-1; i++){
		fin >> nod_1 >> nod_2;
		parent[nod_2] = nod_1;
		mat[nod_1].push_back(nod_2);
		mat[nod_2].push_back(nod_1);
	};
	for(int i = 1; i <=n; i++){
		if(!parent[i]){root = i;break;}
	}
};

void precalculare(){
	for(int i = 1; i <=n; i++){
		up[0][i] = parent[i];
	};
	
	for(int j = 1; j <LOG_MAX; j++){
		for(int i = 1; i <=n; i++){
            up[j][i] = up[j-1][up[j-1][i]];
		}
	}
}

int find_ancestor(int nod,int k){
	for(int i = 0; i < LOG_MAX; i++){
		if((1 << i)&k){
			nod = up[i][nod];
		}
	};
	return nod;
}

void solve(int nod){
	int k = k_value[nod],aux = nod;
	for(int i = 0; i < LOG_MAX; i++){
		if((1 << i)&k){
			aux = up[i][aux];
		}
	};
	value[nod] = value[aux]+1;
}

void dfs(int nod){
	visited[nod] = 1;
	for(auto nod_aux : mat[nod]){
		if(!visited[nod_aux]){
			dfs(nod_aux);
		}
	};
	topological_order.push_back(nod);
}

int main(){
	read_input();
	precalculare();
	dfs(root);
	reverse(topological_order.begin(),topological_order.end());
	for(auto x : topological_order){
		solve(x);
	};
	for(int i = 1; i <=n; i++){
		fout << value[i]-1 << " ";
	}
	return 0;
}