Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <algorithm>
- #include <iostream>
- #include <map>
- using namespace std;
- #define f first
- #define s second
- const int MAXN = 2e5 + 3;
- int ind[MAXN];
- int roz[MAXN];
- int odw[MAXN];
- bool was[MAXN];
- long long ans[MAXN];
- vector<int> v[MAXN];
- map<string, int> mp;
- map<int, int> licz;
- map<int, int> licz2;
- int trn = 0;
- int ile;
- void DFS(int x) {
- odw[x] = trn;
- roz[x] = 1;
- licz[ind[x]]++;
- ile++;
- for (auto &it:v[x]) {
- if (!was[it] && odw[it] != trn) {
- DFS(it);
- roz[x] += roz[it];
- }
- }
- }
- void DFS2(int x) {
- odw[x] = trn;
- licz2[ind[x]]++;
- for (auto &it:v[x]) {
- if (!was[it] && odw[it] != trn)
- DFS2(it);
- }
- }
- void DFS3(int x, long long gle) {
- ans[ind[x]] += (licz[ind[x]] - licz2[ind[x]]) * gle;
- odw[x] = trn;
- for (auto &it:v[x]) {
- if (!was[it] && odw[it] != trn)
- DFS3(it, gle + 1);
- }
- }
- int find_centroid(int x) {
- for (auto &it:v[x]) {
- if (!was[it] && roz[it] > roz[x] / 2) {
- roz[x] -= roz[it];
- roz[it] = ile;
- return find_centroid(it);
- }
- }
- return x;
- }
- void rob(int x) {
- trn++;
- ile = 0;
- licz.clear();
- DFS(x);
- int centroid = find_centroid(x);
- was[centroid] = true;
- for (auto &it:v[centroid]) {
- if (!was[it]) {
- licz2.clear();
- trn++;
- DFS2(it);
- trn++;
- DFS3(it, 1);
- }
- }
- for (auto &it:v[centroid]) {
- if (!was[it])
- rob(it);
- }
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- int n, x, y;
- string ss;
- cin >> n;
- for (int i = 1; i < n; i++) {
- cin >> x >> y;
- v[x].push_back(y);
- v[y].push_back(x);
- }
- int cnt = 0;
- for (int i = 1; i <= n; i++) {
- cin >> ss;
- if (!mp[ss])
- mp[ss] = ++cnt;
- ind[i] = mp[ss];
- }
- rob(1);
- for (auto &it:mp)
- printf("%lld\n", ans[it.s]);
- return 0;
- }
Add Comment
Please, Sign In to add comment