Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define F first
- #define S second
- #define pb push_back
- #define mp make_pair
- using namespace std;
- typedef long long ll;
- typedef pair <int, int> pii;
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- using namespace __gnu_pbds;
- #define ordered_set tree<pair<ll,int>, null_type,less<pair<ll,int>>, rb_tree_tag,tree_order_statistics_node_update>
- const int INF = 1e7;
- const ll longINF = 1e17;
- const int mxN = 1e5 + 9;
- const int mxM = 1e5 + 9;
- const int MOD = 998244353;
- const double pi = acos (-1);
- void setIO (string s) {
- freopen ((s + ".in").c_str(), "r", stdin);
- freopen ((s + ".out").c_str(), "w", stdout);
- return;
- }
- struct node {
- int val = 0;
- node *ln, *rn;
- node () {
- ln = rn = NULL;
- val = 0;
- }
- node (const node* node2) {
- ln = node2 -> ln;
- rn = node2 -> rn;
- val = node2 -> val;
- }
- node (int x) {
- val = x;
- ln = rn = NULL;
- }
- node (node* L, node* R) {
- ln = L;
- rn = R;
- val = 0;
- if (L) val += ln -> val;
- if (R) val += rn -> val;
- }
- };
- node* goCopy (node* v, int l, int r, int idx) {
- if (idx < l || idx > r)
- return v;
- if (l == r)
- return new node ((v -> val) + 1);
- int mid = (l + r) >> 1;
- if (v -> ln == NULL)
- v -> ln = new node();
- if (v -> rn == NULL)
- v -> rn = new node();
- return new node (goCopy(v -> ln, l, mid, idx),
- goCopy(v -> rn, mid + 1, r, idx));
- }
- node *segTree[mxN];
- int A[mxN], pa[mxN];
- vector <int> adj[mxN];
- int in[mxN], out[mxN], t = 0, lol;
- int up[mxN][35];
- void DFS (int v, int p) {
- in[v] = ++t;
- up[v][0] = p;
- for (int i = 1; i <= lol; i++)
- up[v][i] = up[up[v][i - 1]][i - 1];
- for (auto u: adj[v]) {
- if (u == p) continue;
- DFS (u, v);
- }
- out[v] = ++t;
- }
- bool chk (int u, int v) {
- return (in[u] <= in[v]) && (out[u] >= out[v]);
- }
- int lca (int u, int v) {
- if (chk(u, v)) return u;
- if (chk(v, u)) return v;
- for (int i = lol; i >= 0; i--)
- if (!chk(up[u][i], v))
- u = up[u][i];
- return up[u][0];
- }
- void goDFS (int v, int p) {
- segTree[v] = goCopy (segTree[p], 0, 1e9 + 1, A[v]);
- pa[v] = p;
- for (auto u: adj[v]) {
- if (u == p)
- continue;
- goDFS (u, v);
- }
- return;
- }
- void validate (node* x) {
- if (x -> ln == NULL)
- x -> ln = new node();
- if (x -> rn == NULL)
- x -> rn = new node();
- return;
- }
- int getQuery (node* u, node* v, node* lc, node* plc, int l, int r, int k) {
- if (l == r) {
- return l;
- }
- validate (u);
- validate (v);
- validate (lc);
- validate (plc);
- int mid = (l + r) >> 1;
- int sumL = (u -> ln -> val) + (v -> ln -> val);
- sumL -= (lc -> ln -> val);
- sumL -= (plc -> ln -> val);
- if (sumL >= k) {
- return getQuery (u -> ln, v -> ln, lc -> ln, plc -> ln, l, mid, k);
- } else return getQuery (u -> rn, v -> rn, lc -> rn, plc -> rn, mid + 1, r, k - sumL);
- }
- void solve () {
- int n, m;
- cin >> n >> m;
- for (int i = 1; i <= n; i++)
- cin >> A[i];
- for (int i = 1; i <= n - 1; i++) {
- int u, v;
- cin >> u >> v;
- adj[u].pb (v);
- adj[v].pb (u);
- }
- segTree[0] = new node();
- goDFS (1, 0);
- DFS (1, 1);
- lol = log2(n);
- while (m--) {
- int u, v, k;
- cin >> u >> v >> k;
- int lcA = lca (u, v);
- cout << u << ' ' << v << ' ' << lca (u, v) << ' ' << lca (v, u) << "\n";
- //cout << getQuery (segTree[v], segTree[v], segTree[lcA], segTree[pa[lcA]], 0, 1e9 + 1, k) << endl;
- }
- return;
- }
- int main () {
- int t = 1;
- //cin >> t;
- ios_base::sync_with_stdio (0);
- cin.tie (0);
- //setIO ("deleg");
- //preCalc ();
- while (t--) {
- //initialize common variables
- //go solve
- solve ();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement