Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define ll long long
- const ll nmax2 = 1e9+7;
- const ll nmax = 998244353;
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- #include <ext/pb_ds/detail/standard_policies.hpp>
- using namespace __gnu_pbds;
- typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
- typedef tree<std::pair<ll, ll>, null_type, less<std::pair<ll,ll>>, rb_tree_tag, tree_order_statistics_node_update> ordered_set_pair;
- ll get_set_bits(ll u){
- return __builtin_popcount(u);
- }
- void solve(){
- ll n;
- std::cin >> n;
- std::vector<ll> a(n + 1);
- for (ll i = 1; i <= n; i++) std::cin >> a[i];
- std::vector<std::vector<ll>> adj(n + 1, std::vector<ll>());
- for (ll i = 1, x, y; i < n; i++){
- std::cin >> x >> y;
- adj[x].push_back(y);
- adj[y].push_back(x);
- }
- ll timer = 1;
- std::vector<ll> tin(n + 1);
- std::vector<ll> tout(n + 1);
- std::vector<ll> dist(n + 1);
- ll next[n + 1][31];
- for (ll i = 0; i <= n; i++){
- for (ll j = 0; j <= 30; j++) next[i][j] = -1;
- }
- std::function<bool(ll, ll)> is_ancestor = [&] (ll u, ll v){
- if (u == -1 or v == -1) return false;
- return ((tin[u] <= tin[v]) && (tout[u] >= tout[v]));
- };
- std::vector<ll> b(n + 1, -1);
- ll lca[n + 1][21];
- ll or_calc[n + 1][21];
- for (ll i = 0; i <= n; i++){
- for (ll j = 0; j <= 20; j++){
- lca[i][j] = -1;
- or_calc[i][j] = 0;
- }
- }
- std::function<ll(ll, ll)> get_lca = [&] (ll u, ll v){
- if (is_ancestor(u, v)){
- return u;
- }
- if (is_ancestor(v, u)){
- return v;
- }
- for (ll i = 20; i >= 0; i--){
- if (lca[u][i] == -1) continue;
- if (!is_ancestor(lca[u][i], v)){
- u = lca[u][i];
- }
- }
- return lca[u][0];
- };
- std::function<void(ll, ll)> dfs = [&] (ll u, ll p) {
- tin[u] = timer++;
- for (ll i = 30; i >= 0; i--){
- if ((a[u] >> i) & 1){
- b[i] = u;
- }
- next[u][i] = b[i];
- }
- lca[u][0] = p;
- or_calc[u][0] = a[u];
- if (p != -1) or_calc[u][0] |= a[p];
- for (ll i = 1; i <= 20; i++){
- if (lca[u][i - 1] != -1){
- lca[u][i] = lca[lca[u][i - 1]][i - 1];
- or_calc[u][i] = or_calc[u][i - 1] | or_calc[lca[u][i - 1]][i - 1];
- } else{
- or_calc[u][i] = or_calc[u][i - 1];
- }
- }
- for (auto v: adj[u]){
- if (v == p) continue;
- dist[v] = dist[u] + 1;
- dfs(v, u);
- }
- tout[u] = timer++;
- };
- dfs(1, -1);
- std::function<ll(ll, ll)> calc_or = [&] (ll u, ll v){
- ll ans = 0;
- for (ll i = 20; i >= 0; i--){
- if (lca[u][i] == -1) continue;
- if (is_ancestor(v, lca[u][i])){
- ans |= or_calc[u][i];
- u = lca[u][i];
- }
- }
- return ans;
- };
- std::function<ll(ll, ll)> _path_or = [&] (ll u, ll v){
- ll l = get_lca(u, v);
- ll res = calc_or(u, l) | calc_or(v, l);
- return res;
- };
- ll q;
- std::cin >> q;
- for (ll i = 1, x, y; i <= q; i++){
- std::cin >> x >> y;
- std::vector<ll> temp;
- ll fin = 0;
- ll l = get_lca(x, y);
- for (ll j = 0; j <= 30; j++){
- if (next[x][j] != -1 and is_ancestor(l, next[x][j])){
- temp.push_back(next[x][j]);
- }
- if (next[y][j] != -1 and is_ancestor(l, next[y][j])){
- temp.push_back(next[y][j]);
- }
- }
- for (auto w: temp){
- fin = std::max(fin, 1LL * get_set_bits(_path_or(x, w)) + 1LL * get_set_bits(_path_or(w, y)));
- }
- std::cout << fin << " \n"[i == q];
- }
- }
- int main(){
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(0);
- std::cout.tie(0);
- int t;
- std::cin >> t;
- // t = 1;
- while(t--){
- solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement