-
Notifications
You must be signed in to change notification settings - Fork 67
/
ADATOMEL.cpp
117 lines (107 loc) · 3.03 KB
/
ADATOMEL.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
//
// main.cpp
// practice
//
// Created by Mahmud on 11/02/17.
// Copyright © 2017 Mahmud. All rights reserved.
//
/*
O(N + Q * log(N) * MAX(K) / 32) solution using bitsets
MAX(K) defines maximum of colors which can be up to 1000
32 factor comes from bitsets (basically, 32 times faster than normal boolean array)
For more precise definition of bitsets, please google it.
Every query is just combination of 3 paths which can be handled seperately and results are better
to be merged using bitsets.
Binary lifting method is used for answering LCA(lowest common ancestor) queries rapidly.
Although bitsets are powerful due to their 32 (even 64 -> depends on implementation) times faster
performance, usually intended solutions are different from those using bitsets.
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <bitset>
using namespace std;
const int MAX = 300005;
const int MAGIC = 1001;
const int LOG = 19;
int N, K, Q;
int color[MAX];
int depth[MAX], parent[LOG][MAX];
bitset<MAGIC> bs[LOG][MAX];
vector<int> edges[MAX];
void dfs(int node, int parent) {
for (int i : edges[node]) {
if (i != parent) {
depth[i] = depth[node] + 1;
dfs(i, node);
}
}
}
int LCA(int a, int b) {
if (depth[a] < depth[b]) {
swap(a, b);
}
for (int i = LOG - 1; i >= 0; i --) {
if (depth[a] - (1 << i) >= depth[b]) {
a = parent[i][a];
}
}
if (a == b) {
return a;
}
for (int i = LOG - 1; i >= 0; i --) {
if (parent[i][a] != parent[i][b]) {
a = parent[i][a];
b = parent[i][b];
}
}
return parent[0][a];
}
int main() {
scanf("%d%d%d", &N, &K, &Q);
for (int i = 2; i <= N; i ++) {
scanf("%d", &parent[0][i]);
++parent[0][i];
edges[parent[0][i]].push_back(i);
}
for (int i = 1; i <= N; i ++) {
scanf("%d", &color[i]);
bs[0][i][color[i]] = 1;
if (parent[0][i] != 0) {
bs[0][i][color[parent[0][i]]] = 1;
}
}
for (int i = 1; i < LOG; i ++) {
for (int j = 1; j <= N; j ++) {
if (parent[i - 1][j] != 0) {
parent[i][j] = parent[i - 1][parent[i - 1][j]];
bs[i][j] = bs[i - 1][j] | bs[i - 1][parent[i - 1][j]];
}
}
}
dfs(1, -1);
while (Q --) {
int u, v;
bitset<MAGIC> result;
for (int i = 0; i < 3; i ++) {
scanf("%d%d", &u, &v);
++u;
++v;
int l = LCA(u, v);
for (int i = LOG - 1; i >= 0; i --) {
if (depth[u] - (1 << i) >= depth[l]) {
result |= bs[i][u];
u = parent[i][u];
}
}
for (int i = LOG - 1; i >= 0; i --) {
if (depth[v] - (1 << i) >= depth[l]) {
result |= bs[i][v];
v = parent[i][v];
}
}
}
printf("%d\n", (int)result.count());
}
return 0;
}