#define fast ios::sync_with_stdio(false); cin.tie(0)
#define foru(i, k, n) for (int i = k; i < n; i++)
#define ford(i, k, n) for (int i = k; i >= n; i--)
#define pb push_back
#define mp make_pair
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <bitset>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template<class T>
struct rmq {
vector<vector<T>> a;
vector<int> logs;
int dep, len;
rmq(vector<T> arr) {
len = arr.size();
dep = 0;
int tmp = len;
while (tmp) {
tmp >>= 1;
dep++;
}
a.resize(dep);
foru(i, 0, dep) {
a[i].resize(len);
for (int j = 0; j + (1 << i) <= len; j++) {
if (!i)a[i][j] = arr[j];
else a[i][j] = min(a[i - 1][j], a[i - 1][j + (1 << (i - 1))]);
}
}
initLogs();
}
void initLogs() {
logs.resize(len + 1);
logs[1] = 0;
foru(i, 2, len + 1)logs[i] = logs[i >> 1] + 1;
}
T query(int l, int r) {
int mylen = logs[r - l + 1];
return min(a[mylen][l], a[mylen][r - (1 << mylen) + 1]);
}
};
struct lca {
vector<vector<int>> adj;
vector<int> appear;
vector<pii> dep;
rmq<pii>* tree;
int sz;
lca(vector<vector<int>> adjacency) {
adj = adjacency;
sz = adjacency.size();
appear.resize(sz);
dfsscan(0, -1, 0);
tree = new rmq<pii>(dep);
}
void dfsscan(int src, int prev, int currdep) {
appear[src] = dep.size();
dep.pb(mp(currdep, src));
for (auto x : adj[src]) {
if (x == prev)continue;
dfsscan(x, src, currdep + 1);
dep.pb(mp(currdep, src));
}
}
int query(int a, int b) {
int x = min(appear[a], appear[b]), y = max(appear[a], appear[b]);
return tree->query(x, y).second;
}
};
const int sz = 5e5 + 5;
int cntreg[sz], reg[sz], reglca[sz], n, k, dep[sz];
vector<vector<int>> adj;
vector<int> myreg[sz];
bitset<sz> isFull, isUpFull;
void dfsdep(int src, int prv) {
for (int x : adj[src]) {
if (x != prv) {
dep[x] = dep[src] + 1;
dfsdep(x, src);
}
}
}
pair<bool, int> dfs(int src, int prv) {
bool isDownFull = 0;
int curmaxlca = reglca[reg[src]];
for (int x : adj[src]) {
if (x != prv) {
auto tmp = dfs(x, src);
isDownFull |= tmp.first;
if (dep[tmp.second] < dep[curmaxlca])
curmaxlca = tmp.second;
}
}
isFull[src] = (curmaxlca == src);
isUpFull[src] = (isFull[src] && !isDownFull);
return { isDownFull, curmaxlca };
}
int main() {
fast;
cin >> n >> k;
adj.resize(n);
foru(i, 0, n - 1) {
int x, y;
cin >> x >> y;
adj[--x].pb(--y);
adj[y].pb(x);
}
foru(i, 0, n)
cin >> reg[i], cntreg[reg[i]]++, myreg[reg[i]].pb(i);
dfsdep(0, -1);
lca tre(adj);
for (int i = 1; i <= k; i++) {
reglca[i] = myreg[i][0];
for (int j = 1; j < myreg[i].size(); j++)
reglca[i] = tre.query(reglca[i], myreg[i][j]);
}
dfs(0, -1);
isUpFull[0] = 0;
cout << (isUpFull.count() + 1) / 2 << '\n';
return 0;
}
Compilation message
mergers.cpp: In function 'int main()':
mergers.cpp:128:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
128 | for (int j = 1; j < myreg[i].size(); j++)
| ~~^~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
12140 KB |
Output is correct |
2 |
Correct |
10 ms |
12140 KB |
Output is correct |
3 |
Correct |
8 ms |
12140 KB |
Output is correct |
4 |
Correct |
8 ms |
12140 KB |
Output is correct |
5 |
Correct |
8 ms |
12140 KB |
Output is correct |
6 |
Correct |
8 ms |
12140 KB |
Output is correct |
7 |
Correct |
8 ms |
12140 KB |
Output is correct |
8 |
Correct |
8 ms |
12140 KB |
Output is correct |
9 |
Incorrect |
8 ms |
12140 KB |
Output isn't correct |
10 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
12140 KB |
Output is correct |
2 |
Correct |
10 ms |
12140 KB |
Output is correct |
3 |
Correct |
8 ms |
12140 KB |
Output is correct |
4 |
Correct |
8 ms |
12140 KB |
Output is correct |
5 |
Correct |
8 ms |
12140 KB |
Output is correct |
6 |
Correct |
8 ms |
12140 KB |
Output is correct |
7 |
Correct |
8 ms |
12140 KB |
Output is correct |
8 |
Correct |
8 ms |
12140 KB |
Output is correct |
9 |
Incorrect |
8 ms |
12140 KB |
Output isn't correct |
10 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
12140 KB |
Output is correct |
2 |
Correct |
10 ms |
12140 KB |
Output is correct |
3 |
Correct |
8 ms |
12140 KB |
Output is correct |
4 |
Correct |
8 ms |
12140 KB |
Output is correct |
5 |
Correct |
8 ms |
12140 KB |
Output is correct |
6 |
Correct |
8 ms |
12140 KB |
Output is correct |
7 |
Correct |
8 ms |
12140 KB |
Output is correct |
8 |
Correct |
8 ms |
12140 KB |
Output is correct |
9 |
Incorrect |
8 ms |
12140 KB |
Output isn't correct |
10 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
135 ms |
63452 KB |
Output is correct |
2 |
Correct |
141 ms |
66656 KB |
Output is correct |
3 |
Incorrect |
12 ms |
13548 KB |
Output isn't correct |
4 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
8 ms |
12140 KB |
Output is correct |
2 |
Correct |
10 ms |
12140 KB |
Output is correct |
3 |
Correct |
8 ms |
12140 KB |
Output is correct |
4 |
Correct |
8 ms |
12140 KB |
Output is correct |
5 |
Correct |
8 ms |
12140 KB |
Output is correct |
6 |
Correct |
8 ms |
12140 KB |
Output is correct |
7 |
Correct |
8 ms |
12140 KB |
Output is correct |
8 |
Correct |
8 ms |
12140 KB |
Output is correct |
9 |
Incorrect |
8 ms |
12140 KB |
Output isn't correct |
10 |
Halted |
0 ms |
0 KB |
- |