Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define task "COUNTPROBS"
- #include <iostream>
- #include <cstdio>
- #include <vector>
- #include <cassert>
- using namespace std;
- using ll = long long;
- using ld = long double;
- template <class T>
- void read(T &x)
- {
- x = 0;
- register int c;
- while ((c = getchar()) && (c > '9' || c < '0'))
- ;
- for (; c >= '0' && c <= '9'; c = getchar())
- x = x * 10 + c - '0';
- }
- constexpr int N = 1e6 + 5;
- int n, m, l;
- vector<int> goodat[N], adj[N];
- vector<int> allvers[N * 3];
- int x[N * 2][21], ranks[N];
- int sumup[N], in[N];
- void Read()
- {
- // assert(cin >> n >> m);
- read(n), read(m);
- for (int i = 1; i <= n; ++i)
- {
- int t;
- // assert(cin >> t);
- read(t);
- goodat[i].resize(t);
- for (auto &j : goodat[i])
- // assert(cin >> j);
- read(j);
- }
- for (int i = 2; i <= n; ++i)
- {
- int p;
- // assert(cin >> p);
- read(p);
- adj[p].emplace_back(i);
- }
- }
- void dfs(int v)
- {
- x[in[v] = ++l][0] = v;
- for (int i : adj[v])
- {
- ranks[i] = ranks[v] + 1;
- dfs(i);
- x[++l][0] = v;
- }
- }
- int LCA(int u, int v)
- {
- int l = in[u], r = in[v];
- if (l > r)
- swap(l, r);
- int loga = __lg(r - l + 1);
- if (ranks[x[l][loga]] < ranks[x[r - (1 << loga) + 1][loga]])
- return x[l][loga];
- return x[r - (1 << loga) + 1][loga];
- }
- void Solve()
- {
- ranks[1] = 1;
- dfs(1);
- for (int i = l; i; --i)
- if (i == in[x[i][0]])
- for (auto j : goodat[x[i][0]])
- allvers[j].emplace_back(x[i][0]);
- // LCA O(1)
- for (int i = 1; i < 21; ++i)
- for (int j = 1; j <= l - (1 << i) + 1; ++j)
- x[j][i] = (ranks[x[j][i - 1]] < ranks[x[j + (1 << (i - 1))][i - 1]] ? x[j][i - 1] : x[j + (1 << (i - 1))][i - 1]);
- for (int i = 1; i <= m; ++i)
- {
- for (int j = 0; j < (int)allvers[i].size(); ++j)
- {
- ++sumup[allvers[i][j]];
- if (j != (int)allvers[i].size() - 1)
- --sumup[LCA(allvers[i][j], allvers[i][j + 1])];
- }
- }
- for (int i = l; i; --i)
- if (i == in[x[i][0]])
- for (auto j : adj[x[i][0]])
- sumup[x[i][0]] += sumup[j];
- for (int i = 1; i <= n; ++i)
- cout << sumup[i] << " ";
- }
- int32_t main()
- {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- if (fopen(task ".INP", "r"))
- {
- freopen(task ".INP", "r", stdin);
- freopen(task ".OUT", "w", stdout);
- }
- Read();
- Solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement