Идея: arsen1y
Идея: eyfxrby
Идея: arsen1y
2236D - Brand New Tatar TV Show
Идея: dvb1r
Идея: arsen1y
2236F1 - Elections in Saransk (easy version)
Идея: eyfxrby
2236F2 - Elections in Saransk (hard version)
Идея: eyfxrby
2236G - Criterion in Burlandia
Идея: dvb1r
<spoiler summary="Решение 2 (Treks)" ~~~~~ //#pragma GCC optimize("Ofast") //#pragma GCC optimize("O3,unroll-loops")
include <bits/stdc++.h>
include <experimental/random>
include <ext/pb_ds/assoc_container.hpp>
using namespace std; using namespace __gnu_pbds;
using ll = long long; using ld = long double; using ordered_set = tree<ll, null_type, less, rb_tree_tag, tree_order_statistics_node_update>; using str = string; const ll INF = 1e18, MOD = 1e9 + 7; template using pq_min = priority_queue<T, vector, greater>; template using pq_max = priority_queue<T, vector, less>;
define int long long
void solve();
signed main() {
ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll q = 1;
cin >> q;
while (q--) {
solve();
//cout << "\n";
}}
vector<vector> g; vector a; int h; vector us; int cnt1; vector T;
void dfs1(int v, int pr) { T.push_back(v); cnt1++; for (auto to: g[v]) { if (to != pr && !us[to]) { dfs1(to, v); } } }
int dfs(int v, int pr) { bool p = true; int cnt = 1; for (auto to: g[v]) { if (to != pr && !us[to]) { auto u = dfs(to, v); if (u > cnt1 / 2) { p = false; } cnt += u; } } if (p && (cnt1 — cnt) <= cnt1 / 2) { h = v; } return cnt; }
int E = 0;
vector ans; vector<vector> mn; vector col; vector sz; vector W;
void dfs(int v, int pr, vector s, int an, int o, int mx) { sz[v] = o; col[v] = E; W[v] = W[pr]; for (int i = 0; i < 20; ++i) {
mn[v][i] = mn[pr][i]; } for (int i = 0; i < 20; ++i) { if ((a[v] >> i) & 1) { if (mn[v][i] != INF) { W[v] = min(W[v], o); } mn[v][i] = min(mn[v][i], o); mx = max(mx, s[i]); s[i] = o; } } an += o — mx; ans[v] = an; for (auto to: g[v]) { if (to != pr && !us[to]) { dfs(to, v, s, an, o + 1, mx); } } }
vector<vector<pair<int, int>>> que; vector ANS;
void rec(int v) { T.clear(); cnt1 = 0; dfs1(v, -1); dfs(v, -1); v = h; us[v] = true; mn[v] = vector(20, INF); int S = E; W[v] = INF; for (auto to: g[v]) { if (!us[to]) { E++; vector s(20, 0); dfs(to, v, s, 0, 1, 0); } } ans[v] = 0; ++E; col[v] = E; for (auto x: T) { for (auto [y, id]: que[x]) { if (col[x] != col[y] && col[x] > S && col[y] > S) { ANS[id] = ans[x] + ans[y]; if (x == v) { int MN = min(W[y], sz[y] + 1); for (int i = 0; i < 20; ++i) { if ((a[v] >> i) & 1) { MN = min(MN, mn[y][i]); } } ANS[id] += MN; } else if (y == v) { int MN = min(W[x], sz[x] + 1); for (int i = 0; i < 20; ++i) { if ((a[v] >> i) & 1) { MN = min(MN, mn[x][i]); } } ANS[id] += MN; } else { vector<pair<int, int>> upd; for (int i = 0; i < 20; ++i) { if (mn[x][i] != INF) { upd.push_back({mn[x][i], i}); } } int e = min(W[y], sz[y] + 1); for (int i = 0; i < 20; ++i) { if ((a[v] >> i) & 1) { e = min(e, mn[y][i]); } } sort(upd.begin(), upd.end()); int p = 0; bool flag = true; for (int i = 0; i < upd.size(); ++i) { if (upd[i].first >= W[x]) { ANS[id] += (W[x] — p) * e; flag = false; break; } ANS[id] += (upd[i].first — p) * e; if ((a[v] >> upd[i].second) & 1) { flag = false; break; } e = min(e, mn[y][upd[i].second]); p = upd[i].first; } if (flag) { ANS[id] += (min(W[x], sz[x] + 1) — p) * e; } } } } } for (int i = 0; i < g[v].size(); ++i) { int to = g[v][i]; if (!us[to]) { rec(to); } } }
void solve() { int n, q; cin >> n >> q; sz.clear(); W.clear(); W.resize(n); sz.resize(n); ans.clear(); ANS.clear(); ANS.resize(q, -1); mn.clear(); ans.resize(n); mn.resize(n, vector(20)); a.clear(); us.clear(); us.resize(n); a.resize(n); for (int i = 0; i < n; ++i) { cin >> a[i]; } g.clear(); col.clear(); col.resize(n); que.clear(); que.resize(n); g.resize(n); for (int i = 0; i < n — 1; ++i) { int u, v; cin >> u >> v; --u; --v; g[u].push_back(v); g[v].push_back(u); } for (int i = 0; i < q; ++i) { int x, y; cin >> x >> y; --x; --y; que[x].push_back({y, i}); } rec(0); for (int i = 0; i < q; ++i) { if (ANS[i] == -1) { exit(-1); } cout << ANS[i] << "\n"; } } ~~~~~



