mirror of
https://git.sb/baoshuo/OI-codes.git
synced 2024-11-30 20:16:27 +00:00
136 lines
2.3 KiB
C++
136 lines
2.3 KiB
C++
|
#include <iostream>
|
||
|
#include <algorithm>
|
||
|
#include <cstring>
|
||
|
#include <functional>
|
||
|
#include <unordered_map>
|
||
|
#include <vector>
|
||
|
|
||
|
using std::cin;
|
||
|
using std::cout;
|
||
|
const char endl = '\n';
|
||
|
|
||
|
const int N = 5e5 + 5;
|
||
|
|
||
|
int n, fa[N];
|
||
|
long long a[N], max, ans[N];
|
||
|
std::vector<int> g[N];
|
||
|
std::unordered_map<long long, int> lst;
|
||
|
bool vis[N];
|
||
|
int cnt = 1, tr[N * 60][2];
|
||
|
|
||
|
void insert(long long x) {
|
||
|
int p = 1;
|
||
|
|
||
|
for (int i = 60; i >= 0; i--) {
|
||
|
bool ch = (x >> i) & 1;
|
||
|
|
||
|
if (!tr[p][ch]) {
|
||
|
tr[p][ch] = ++cnt;
|
||
|
}
|
||
|
|
||
|
p = tr[p][ch];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
long long query(long long x) {
|
||
|
int p = 1;
|
||
|
long long res = 0;
|
||
|
|
||
|
for (int i = 60; i >= 0; i--) {
|
||
|
int ch = (x >> i) & 1;
|
||
|
|
||
|
if (!p) break;
|
||
|
|
||
|
if (tr[p][ch ^ 1]) {
|
||
|
res |= 1ll << i;
|
||
|
p = tr[p][ch ^ 1];
|
||
|
} else {
|
||
|
p = tr[p][ch];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
void solve(int x) {
|
||
|
max = 0;
|
||
|
cnt = 1;
|
||
|
memset(tr, 0x00, sizeof(tr));
|
||
|
std::vector<int> vec;
|
||
|
std::vector<bool> vis2(n + 1);
|
||
|
|
||
|
for (int i = x; i; i = fa[i]) {
|
||
|
vec.emplace_back(i);
|
||
|
vis[i] = true;
|
||
|
vis2[i] = true;
|
||
|
}
|
||
|
|
||
|
std::reverse(vec.begin(), vec.end());
|
||
|
|
||
|
std::function<void(int)> get = [&](int u) -> void {
|
||
|
insert(a[u]);
|
||
|
max = std::max(max, query(a[u]));
|
||
|
|
||
|
for (int v : g[u]) {
|
||
|
get(v);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
for (int u : vec) {
|
||
|
ans[u] = max;
|
||
|
|
||
|
for (int v : g[u]) {
|
||
|
if (vis2[v]) continue;
|
||
|
|
||
|
get(v);
|
||
|
}
|
||
|
|
||
|
insert(a[u]);
|
||
|
max = std::max(max, query(a[u]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
std::ios::sync_with_stdio(false);
|
||
|
cin.tie(nullptr);
|
||
|
|
||
|
cin >> n;
|
||
|
|
||
|
for (int i = 2; i <= n; i++) {
|
||
|
cin >> fa[i];
|
||
|
|
||
|
g[fa[i]].emplace_back(i);
|
||
|
}
|
||
|
|
||
|
for (int i = 1; i <= n; i++) {
|
||
|
cin >> a[i];
|
||
|
}
|
||
|
|
||
|
for (int i = 1; i <= n; i++) {
|
||
|
max = std::max(max, query(a[i]));
|
||
|
insert(a[i]);
|
||
|
}
|
||
|
|
||
|
int x = 1, y = 1;
|
||
|
|
||
|
for (int i = 1; i <= n; i++) {
|
||
|
lst[a[i]] = i;
|
||
|
|
||
|
if (lst.count(a[i] ^ max)) {
|
||
|
x = i;
|
||
|
y = lst[a[i] ^ max];
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
solve(x);
|
||
|
solve(y);
|
||
|
|
||
|
for (int i = 1; i <= n; i++) {
|
||
|
cout << (vis[i] ? ans[i] : max) << endl;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|