Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query (线段树)
2017-11-29 20:47
555 查看
题目链接:http://codeforces.com/contest/893/problem/F
这个题好像挺傻逼的啊?
首先dfs序,然后线段树维护,每个节点维护一个vector表示这个区间中所有的节点的深度,这样的空间复杂度为O(nlogn),因为不涉及修改,咱们的对每个节点的vector都进行排序,然后每次按照区间查询就好了,貌似不用树套树,这个题就很好写了啊?
代码:
这个题好像挺傻逼的啊?
首先dfs序,然后线段树维护,每个节点维护一个vector表示这个区间中所有的节点的深度,这样的空间复杂度为O(nlogn),因为不涉及修改,咱们的对每个节点的vector都进行排序,然后每次按照区间查询就好了,貌似不用树套树,这个题就很好写了啊?
代码:
#define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<algorithm> #include<vector> #include<cstring> #include<assert.h> #include<iostream> #define mp make_pair #define xx first #define yy second using namespace std; const int MAXN = 1e5 + 5; const int INF = 0x3f3f3f3f; typedef pair<int, int> pii; struct edge { int v, nxt; }E[MAXN*2]; struct node { vector<pii> sv; vector<int> mi; int query(int k) { int ret = upper_bound(sv.begin(), sv.end(), mp(k,INF)) - sv.begin(); if (ret == 0) return INF; ret--; return mi[ret]; } void push(pii k) { sv.push_back(k); } void Sort() { sort(sv.begin(), sv.end()); int tmp = INF; for (auto i : sv) { tmp = min(tmp, i.yy); //assert(tmp >= 0); mi.push_back(tmp); } } }; struct seg { #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 node tr[MAXN << 2]; void update(int pos, pii val, int l, int r, int rt) { tr[rt].push(val); if (l == r) return; int mid = (l + r) >> 1; if (mid >= pos) update(pos, val, lson); if (mid < pos) update(pos, val, rson); } int query(int L, int R,int val, int l, int r, int rt) { if (L <= l&&r <= R) return tr[rt].query(val); int mid = (l + r) >> 1; int ret = INF; if (mid >= L) ret = min(ret, query(L, R, val, lson)); if (mid < R) ret = min(ret, query(L, R, val, rson)); return ret; } void build(int l, int r, int rt) { tr[rt].Sort(); if (l == r) return; int mid = (l + r) >> 1; build(lson); build(rson); } }se; int n, root, q, tot, tim; int in[MAXN], out[MAXN], dep[MAXN], a[MAXN],head[MAXN]; void addedge(int u, int v) { E[tot].v = v;E[tot].nxt = head[u];head[u] = tot++; E[tot].v = u;E[tot].nxt = head[v];head[v] = tot++; } void init() { memset(head, -1, sizeof(head)); tot = 0, tim = 0; } void dfs(int now, int fa,int dp) { in[now] = ++tim; dep[now] = dp; se.update(in[now], mp(dp, a[now]), 1, n, 1); for (int i = head[now];~i;i = E[i].nxt) { int v = E[i].v; if (v == fa) { continue; } dfs(v, now, dp + 1); } out[now] = tim; } void solve() { int q; init(); scanf("%d%d", &n, &root); for (int i = 1;i <= n;i++) { scanf("%d", &a[i]); } for (int i = 1;i < n;i++) { int u, v; scanf("%d%d",&u,&v); addedge(u, v); } dfs(root, 0, 1); se.build(1, n, 1); scanf("%d", &q); int last = 0; while (q--) { int x, k; scanf("%d%d", &x, &k); x = (x + last) % n + 1;k = (k+ last) % n; printf("%d\n", last=se.query(in[x], out[x], dep[x] + k, 1, n, 1)); } } int main() { solve(); }
相关文章推荐
- Educational Codeforces Round 33 (Rated for Div. 2) F - Subtree Minimum Query
- Educational Codeforces Round 33 F. Subtree Minimum Query
- Educational Codeforces Round 33 (Rated for Div. 2)
- Educational Codeforces Round 33 (Rated for Div. 2)A-F
- Educational Codeforces Round 37 (Rated for Div. 2) F. SUM and REPLACE(线段树)
- Educational Codeforces Round 33 (Rated for Div. 2)A-F
- Educational Codeforces Round 37 (Rated for Div. 2) F. SUM and REPLACE(线段树,区间更新)
- codeforces Educational Codeforces Round 33 (Rated for Div. 2)B
- Educational Codeforces Round 33 (Rated for Div. 2) C
- Educational Codeforces Round 33 (Rated for Div. 2) 题解
- Educational Codeforces Round 37 (Rated for Div. 2)-F-SUM and REPLACE(线段树)
- Educational Codeforces Round 33 (Rated for Div. 2) A - Chess For Three
- Educational Codeforces Round 33 (Rated for Div. 2) D. Credit Card
- Educational Codeforces Round 33 (Rated for Div. 2)【C】【并查集】
- Educational Codeforces Round 33 (Rated for Div. 2) B - Beautiful Divisors
- Educational Codeforces Round 33 (Rated for Div. 2)
- Educational Codeforces Round 33 (Rated for Div. 2) C - Rumor
- Educational Codeforces Round 33 (Rated for Div. 2) A-C题解
- Educational Codeforces Round 37 (Rated for Div. 2) 【F】【线段树】
- Educational Codeforces Round 33 (Rated for Div. 2) D题. Credit Card(贪心)