-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDistinct Colors.cpp
134 lines (133 loc) · 2.78 KB
/
Distinct Colors.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define AB_BHI_NI_DEGI \
ios_base::sync_with_stdio(false); \
cin.tie(NULL); \
cout.tie(NULL);
#define int long long
#define pb push_back
#define N 100009
#define inf 1e18
const double PI = 3.141592653589793238462643383279;
int mod = 1e9 + 7;
//int mod = 998244353;
#define P pair<int, int>
#define F first
#define S second
#define all(v) v.begin(), v.end()
#define vi vector<int>
#define ld long double
#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
vector<int> G[2 * N];
int val[2 * N];
int Euler[4 * N];
int BIT[4 * N];
int in[2 * N], out[2 * N];
int timer;
void dfs(int u, int p)
{
int x = ++timer;
Euler[x] = val[u];
in[u] = x;
for (int v : G[u])
{
if (v != p)
{
dfs(v, u);
}
}
x = ++timer;
Euler[x] = val[u];
out[u] = x;
}
void add(int i, int val)
{
while (i < 4 * N)
{
BIT[i] += val;
i += i & (-i);
}
}
int get(int i)
{
int res = 0;
while (i > 0)
{
res += BIT[i];
i -= i & (-i);
}
return res;
}
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> val[i];
// compress the values of color
map<int, int> compress;
for (int i = 1; i <= n; i++)
compress[val[i]] = 1;
int col = 1;
for (auto it : compress)
{
compress[it.first] = col++;
}
for (int i = 1; i <= n; i++)
val[i] = compress[val[i]];
for (int i = 2; i <= n; i++)
{
int u, v;
cin >> u >> v;
//v = i;
G[u].pb(v);
G[v].pb(u);
}
dfs(1, 0);
// now the question is finding distict elements in Euler array
// between out[i] and in[i] for each node i.
vector<vector<int>> Query;
for (int i = 1; i <= n; i++)
{
Query.pb({in[i], out[i], i});
}
sort(all(Query), [&](vi a, vi b) {
return a[1] < b[1];
});
int vis[n + 1];
memset(vis, -1, sizeof(vis));
int ans[n + 1];
int q = 0;
for (int i = 1; i <= 2 * n; i++)
{
if (vis[Euler[i]] != -1)
add(vis[Euler[i]], -1);
vis[Euler[i]] = i;
add(i, 1);
while (q < Query.size() and Query[q][1] == i)
{
ans[Query[q][2]] = get(Query[q][1]) - get(Query[q][0] - 1);
q++;
}
}
for (int i = 1; i <= n; i++)
cout << ans[i] << " ";
cout << "\n";
}
int32_t main()
{
AB_BHI_NI_DEGI
int Test = 1;
//cin >> Test;
//init();
int itr = 1;
while (Test--)
{
//cout << "Case #" << itr++ << ": ";
solve();
}
return 0;
}