Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- const int MAXN = 123234;
- const int INF = (int)2e9 + 7;
- vector<int>g[MAXN];
- int a[MAXN];
- int tin[MAXN], tout[MAXN];
- int tin2[MAXN];
- int vert[MAXN];
- bool addTime[MAXN];
- bool used[MAXN];
- int timer = 1;
- int timer2 = 1;
- void dfs(int v)
- {
- tin[v] = timer;
- tin2[v] = timer2;
- vert[timer2] = v;
- addTime[timer2] = true;
- timer2++;
- used[v] = true;
- timer++;
- for (int i = 0; i < (int)g[v].size(); i++)
- {
- int to = g[v][i];
- if (!used[to])
- {
- dfs(to);
- vert[timer2] = v;
- addTime[timer2] = true;
- timer2++;
- }
- }
- tout[v] = timer;
- vert[timer] = v;
- addTime[timer] = false;
- timer++;
- }
- bool isAncestor(int u, int v)
- {
- return tin[u] <= tin[v] && tout[u] >= tout[v];
- }
- struct data
- {
- bool haveAlive;
- int minVal;
- int maxVal;
- int res;
- data()
- {
- haveAlive = false;
- minVal = 0;
- maxVal = 0;
- res = (int)2e9 + 7;
- }
- };
- void merge(data& res, const data& l, const data& r)
- {
- res.haveAlive = l.haveAlive | r.haveAlive;
- res.res = INF;
- if (l.haveAlive)
- {
- res.minVal = l.minVal;
- res.res = min(res.res, l.res);
- }
- else
- {
- res.minVal = r.minVal;
- }
- if (r.haveAlive)
- {
- res.maxVal = r.maxVal;
- res.res = min(res.res, r.res);
- }
- else
- {
- res.maxVal = l.maxVal;
- }
- if (l.haveAlive && r.haveAlive)
- {
- res.res = min(res.res, r.minVal - l.maxVal);
- }
- }
- pair<int, int>nodes[MAXN];
- int nodePos[MAXN];
- struct segmentTree
- {
- vector<data> tree;
- segmentTree(){}
- segmentTree(int n)
- {
- tree.resize(4 * n + 17);
- }
- void build(int v, int tl, int tr)
- {
- if (tl == tr)
- {
- tree[v].minVal = nodes[tl].first;
- tree[v].maxVal = nodes[tl].first;
- }
- else
- {
- int tm = (tl + tr) >> 1;
- build(v + v, tl, tm);
- build(v + v + 1, tm + 1, tr);
- merge(tree[v], tree[v + v], tree[v + v + 1]);
- }
- }
- void make(int v, int tl, int tr, int pos, bool active)
- {
- if (tl == tr)
- {
- tree[v].haveAlive = active;
- }
- else
- {
- int tm = (tl + tr) >> 1;
- if (pos <= tm)
- {
- make(v + v, tl, tm, pos, active);
- }
- else
- {
- make(v + v + 1, tm + 1, tr, pos, active);
- }
- merge(tree[v], tree[v + v], tree[v + v + 1]);
- }
- }
- int solve1()
- {
- return tree[1].res;
- }
- int solve2()
- {
- return tree[1].maxVal - tree[1].minVal;
- }
- };
- segmentTree st;
- int BUBEN;
- int curCnt[MAXN];
- bool onPath[MAXN];
- int n;
- void process(int v, int newv, int other)
- {
- if (onPath[newv])
- {
- st.make(1, 1, n, nodePos[v], false);
- onPath[v] = false;
- }
- else
- {
- st.make(1, 1, n, nodePos[newv], true);
- onPath[newv] = true;
- }
- }
- struct query
- {
- int l, r;
- bool C;
- int id;
- };
- bool operator<(query a, query b)
- {
- if (a.l / BUBEN != b.l / BUBEN) return a.l < b.l;
- int block = a.l / BUBEN;
- return (block % 2) ^ (a.r < b.r);
- }
- query q[MAXN];
- int res[MAXN];
- int main()
- {
- //freopen("input.txt", "r", stdin);
- scanf("%d", &n);
- st = segmentTree(n + 1);
- for (int i = 1; i <= n; i++)
- {
- scanf("%d", &a[i]);
- nodes[i].first = a[i];
- nodes[i].second = i;
- }
- sort(nodes + 1, nodes + 1 + n);
- st.build(1, 1, n);
- for (int i = 1; i <= n; i++)
- {
- nodePos[nodes[i].second] = i;
- }
- for (int i = 1; i < n; i++)
- {
- int u, v;
- scanf("%d %d", &u, &v);
- g[u].push_back(v);
- g[v].push_back(u);
- }
- dfs(1);
- BUBEN = sqrt(timer2);
- int qq;
- scanf("%d\n", &qq);
- for (int i = 1; i <= qq; i++)
- {
- char type;
- int u, v;
- scanf("%c %d %d\n", &type, &u, &v);
- int l = tin2[u], r = tin2[v];
- if (l > r) swap(l, r);
- q[i].l = l;
- q[i].r = r;
- q[i].C = (type == 'C');
- q[i].id = i;
- }
- sort(q + 1, q + 1 + qq);
- int l = 1, r = 1;
- onPath[1] = true;
- st.make(1, 1, n, nodePos[1], true);
- for (int i = 1; i <= qq; i++)
- {
- while (r < q[i].r)
- {
- r++;
- process(vert[r - 1], vert[r], vert[l]);
- }
- while (l > q[i].l)
- {
- l--;
- process(vert[l + 1], vert[l], vert[r]);
- }
- while (r > q[i].r)
- {
- process(vert[r], vert[r - 1], vert[l]);
- r--;
- }
- while (l < q[i].l)
- {
- process(vert[l], vert[l + 1], vert[r]);
- l++;
- }
- // magic.print();
- if (q[i].C)
- {
- res[q[i].id] = st.solve1();
- }
- else
- {
- res[q[i].id] = st.solve2();
- }
- }
- for (int i = 1; i <= qq; i++)
- {
- printf("%d\n", res[i]);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement