Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include "optimization.h"
- using namespace std;
- const long long N = 1e6 + 2;
- long long t[4 * N + 2];
- long long level[N];
- long long n, m, q, l, r, timer, x;
- struct T {
- long long l, r, id;
- bool operator<(T q) {
- if (r == q.r)
- return l < q.l;
- return r < q.r;
- }
- };
- vector<T> Q;
- vector<long long> ans;
- vector<long long> pr;
- long long a[N];
- long long pred[N];
- long long t_in[N];
- long long t_out[N];
- vector<long long> g[N];
- long long color[N];
- long long used[N];
- void dfs(long long v) {
- used[v] = 1;
- timer++;
- a[timer] = color[v];
- t_in[v] = timer;
- for(size_t i = 0; i < g[v].size(); i++) {
- long long to = g[v][i];
- if (!used[to]) dfs(to);
- }
- t_out[v] = timer;
- }
- struct SegTree {
- void set(long long i, int x) {
- t[i += n] += x;
- for (i /= 2; i >= 1; i /= 2)
- t[i] = t[2 * i] + t[2 * i + 1];
- }
- int count(int l, int r) {
- long long res = 0;
- for (l += n, r += n; l <= r; l /= 2, r /= 2) {
- if (l % 2 == 1) res += t[l++];
- if (r % 2 == 0) res += t[r--];
- }
- return res;
- }
- };
- SegTree tree;
- int main() {
- n = readInt();
- pr.resize(n + 1);
- long long rt, c, p;
- for (int i = 1; i <= n; i++) {
- p = readInt(), c = readInt();
- rt = (p == 0) ? i : rt;
- g[p].push_back(i);
- color[i] = c;
- pr[i] = -1;
- }
- dfs(rt);
- for (int i = 1; i <= n; i++) {
- pred[i] = pr[a[i]];
- pr[a[i]] = i;
- }
- ans.resize(n + 1);
- for (int i = 1; i <= n; i++) {
- Q.push_back({t_in[i], t_out[i], i});
- }
- sort(Q.begin(), Q.end());
- int pos = 1;
- for (size_t i = 0; i < Q.size(); i++) {
- while(pos <= Q[i].r) {
- if (pred[pos] != -1)
- tree.set(pred[pos], -1);
- tree.set(pos, 1);
- pos++;
- }
- ans[Q[i].id] = tree.count(Q[i].l, Q[i].r);
- }
- for (long long i = 1; i <= n; i++)
- writeInt<long long>(ans[i], ' ');
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement