Algorithm: Persistent Trie
#include "bits/stdc++.h"
using namespace std;
#define int long long int
#define endl '\n'
const int maxn = 3e5 + 5;
const int maxbit = 62;
const int MAXNODES = 2e7;
// https://www.hackerearth.com/practice/data-structures/advanced-data-structures/trie-keyword-tree/practice-problems/algorithm/prefix-queries-3-2c111491/
struct Node {
int st, lchild, rchild;
Node(int st = 0, int lchild = 0, int rchild = 0)
: st(st), lchild(lchild), rchild(rchild) {}
};
int NODES;
Node Tree[MAXNODES];
int version[maxn];
int update(int root, int pos, int val, int add) {
int newNode = ++NODES;
Tree[newNode] = Tree[root];
if (pos < 0) {
Tree[newNode].st += add;
return newNode;
}
bool bit = val >> pos & 1LL;
if (bit == 0) {
Tree[newNode].lchild = update(Tree[newNode].lchild, pos - 1, val, add);
} else {
Tree[newNode].rchild = update(Tree[newNode].rchild, pos - 1, val, add);
}
Tree[newNode].st = Tree[ Tree[newNode].lchild ].st + Tree[ Tree[newNode].rchild ].st;
return newNode;
}
int getMaxPrefix(int root, int pos, int val) {
if (pos < 0) {
return 0;
}
bool bit = val >> pos & 1LL;
if (bit == 0 and Tree[ Tree[root].lchild ].st > 0) {
return 1 + getMaxPrefix(Tree[root].lchild, pos - 1, val);
} else if (bit == 1 and Tree[ Tree[root].rchild ].st > 0) {
return 1 + getMaxPrefix(Tree[root].rchild, pos - 1, val);
}
return 0;
}
int n;
int q;
vector<int> arr;
vector<vector<int>> graph;
vector<vector<pair<int, int>>> queries;
vector<vector<int>> level;
vector<int> par;
vector<int> ans;
void dfs(int u = 1, int p = 0, int lvl = 0) {
version[1] = update(version[1], maxbit - 1, arr[u], 1);
for (auto it : queries[u]) {
ans[it.second] = getMaxPrefix(version[1], maxbit - 1, it.first);
}
for (int v : graph[u]) {
if (v == p) {
continue;
}
dfs(v, u);
}
version[1] = update(version[1], maxbit - 1, arr[u], -1);
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cout.precision(12);
bool FILEIO = 1;
if (FILEIO and fopen("in.txt", "r")) {
freopen("in.txt", "r", stdin);
}
int tc;
cin >> tc;
while (tc--) {
cin >> n;
arr.clear(); arr.resize(n + 1);
NODES = 0;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
}
graph.clear(); graph.resize(n + 1);
for (int e = 1; e < n; e++) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
cin >> q;
queries.clear(); queries.resize(n + 1);
for (int i = 0; i < q; i++) {
int v, x;
cin >> v >> x;
queries[x].push_back({v, i});
}
ans.resize(q);
dfs();
for (int x : ans) {
cout << x << ' ';
}
cout << endl;
for (int i = 0; i <= NODES; i++) {
Tree[i] = Node();
}
}
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.