Educational Codeforces Round 33 (Rated for Div. 2) F - Subtree Minimum Query
2017-11-25 21:31
766 查看
F. Subtree Minimum Query
time limit per test6 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
You are given a rooted tree consisting of n vertices. Each vertex has a number written on it; number ai is written on vertex i.
Let’s denote d(i,?j) as the distance between vertices i and j in the tree (that is, the number of edges in the shortest path from i to j). Also let’s denote the k-blocked subtree of vertex x as the set of vertices y such that both these conditions are met:
x is an ancestor of y (every vertex is an ancestor of itself);
d(x,?y)?≤?k.
You are given m queries to the tree. i-th query is represented by two numbers xi and ki, and the answer to this query is the minimum value of aj among such vertices j such that j belongs to ki-blocked subtree of xi.
Write a program that would process these queries quickly!
Note that the queries are given in a modified way.
Input
The first line contains two integers n and r (1?≤?r?≤?n?≤?100000) — the number of vertices in the tree and the index of the root, respectively.
The second line contains n integers a1,?a2,?…,?an (1?≤?ai?≤?109) — the numbers written on the vertices.
Then n?-?1 lines follow, each containing two integers x and y (1?≤?x,?y?≤?n) and representing an edge between vertices x and y. It is guaranteed that these edges form a tree.
Next line contains one integer m (1?≤?m?≤?106) — the number of queries to process.
Then m lines follow, i-th line containing two numbers pi and qi, which can be used to restore i-th query (1?≤?pi,?qi?≤?n).
i-th query can be restored as follows:
Let last be the answer for previous query (or 0 if i?=?1). Then xi?=?((pi?+?last)?mod?n)?+?1, and ki?=?(qi?+?last)?mod?n.
Output
Print m integers. i-th of them has to be equal to the answer to i-th query.
Example
input
5 2
1 3 2 3 5
2 3
5 1
3 4
4 1
2
1 2
2 3
output
2
5
题意:对于一个树,问一个点,他的所有距离他k距离的儿子的最小值,强制在线。
做法:主席树,先把树做成一个线段树,线段树里ll[x]到rr[x]之间的节点代表x和他的所有儿子,然后按照节点的深度构建主席树,查询的时候,对于节点i和深度k,找出深度在1到dep[i]+k的节点构成的主席树,然后查询ll[x]到rr[x]之间的最小值。
time limit per test6 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
You are given a rooted tree consisting of n vertices. Each vertex has a number written on it; number ai is written on vertex i.
Let’s denote d(i,?j) as the distance between vertices i and j in the tree (that is, the number of edges in the shortest path from i to j). Also let’s denote the k-blocked subtree of vertex x as the set of vertices y such that both these conditions are met:
x is an ancestor of y (every vertex is an ancestor of itself);
d(x,?y)?≤?k.
You are given m queries to the tree. i-th query is represented by two numbers xi and ki, and the answer to this query is the minimum value of aj among such vertices j such that j belongs to ki-blocked subtree of xi.
Write a program that would process these queries quickly!
Note that the queries are given in a modified way.
Input
The first line contains two integers n and r (1?≤?r?≤?n?≤?100000) — the number of vertices in the tree and the index of the root, respectively.
The second line contains n integers a1,?a2,?…,?an (1?≤?ai?≤?109) — the numbers written on the vertices.
Then n?-?1 lines follow, each containing two integers x and y (1?≤?x,?y?≤?n) and representing an edge between vertices x and y. It is guaranteed that these edges form a tree.
Next line contains one integer m (1?≤?m?≤?106) — the number of queries to process.
Then m lines follow, i-th line containing two numbers pi and qi, which can be used to restore i-th query (1?≤?pi,?qi?≤?n).
i-th query can be restored as follows:
Let last be the answer for previous query (or 0 if i?=?1). Then xi?=?((pi?+?last)?mod?n)?+?1, and ki?=?(qi?+?last)?mod?n.
Output
Print m integers. i-th of them has to be equal to the answer to i-th query.
Example
input
5 2
1 3 2 3 5
2 3
5 1
3 4
4 1
2
1 2
2 3
output
2
5
题意:对于一个树,问一个点,他的所有距离他k距离的儿子的最小值,强制在线。
做法:主席树,先把树做成一个线段树,线段树里ll[x]到rr[x]之间的节点代表x和他的所有儿子,然后按照节点的深度构建主席树,查询的时候,对于节点i和深度k,找出深度在1到dep[i]+k的节点构成的主席树,然后查询ll[x]到rr[x]之间的最小值。
#include<bits/stdc++.h> using namespace std; struct node{ int ls,rs,x; }; const int N = 1e5+100; node pt[N*40]; vector<int> G ; queue<pair<int,int> > que; int num ,ll ,rr ,root ,dep ,pos ; bool vis ; int n,r,md,tot,Time; void dfs(int x,int f){ ll[x] = ++Time; int cnt = 1; for(int i = 0;i < G[x].size();i ++){ int v = G[x][i]; if(v == f) continue; dfs(v,x); } rr[x] = Time; } int newnode(){ int rt = tot++; pt[rt].x = 0; pt[rt].ls = 0; pt[rt].rs = 0; return rt; } void build(int &rt,int l,int r){ rt = newnode(); if(l == r){ pt[rt].x = 1e9+100; return ; } int mid = l+r>>1; build(pt[rt].ls,l,mid); build(pt[rt].rs,mid+1,r); pt[rt].x = min(pt[pt[rt].ls].x,pt[pt[rt].rs].x); } void update(int &rt,int bef,int x,int d,int l,int r){ rt = newnode(); if(l == r){ pt[rt].x = d; return ; } int mid = l+r>>1; if(mid >= x){ pt[rt].rs = pt[bef].rs; update(pt[rt].ls,pt[bef].ls,x,d,l,mid); } else{ pt[rt].ls = pt[bef].ls; update(pt[rt].rs,pt[bef].rs,x,d,mid+1,r); } pt[rt].x = min(pt[pt[rt].ls].x,pt[pt[rt].rs].x); } void solve(int id,int x,int d){ dep[x] = d; pos[d] = id; md = max(md,d); update(root[id],root[id-1],ll[x],num[x],1,n); } int query(int rt,int L,int R,int l,int r){ if(L <= l && R >= r){ return pt[rt].x; } int mid = l+r>>1; int ret = 1e9+100; if(mid >= L) ret = query(pt[rt].ls,L,R,l,mid); if(mid < R) ret = min(query(pt[rt].rs,L,R,mid+1,r),ret); return ret; } int main(){ cin >> n >> r; for(int i= 1;i<= n;i ++) scanf("%d",&num[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(r,-1); que.push({r,1}); int cns = 1; build(root[0],1,n); vis[r] = true; while(!que.empty()){ pair<int,int> now = que.front(); que.pop(); solve(cns++,now.first,now.second); for(int i = 0;i < G[now.first].size();i ++){ int v = G[now.first][i]; if(vis[v]) continue; vis[v] = true; que.push({v,now.second+1}); } } int m; cin >> m; int last = 0; for(int i =1;i <= m;i ++){ int qi,qk; scanf("%d %d",&qi,&qk); qi = (last + qi)%n+1; qk = (last + qk)%n; //cout << qi << ' '<< qk <<"!!" << endl; int rt = dep[qi]+qk; rt = min(rt,md); //cout << qi << ' '<< qk << ' '<<dep[pos[rt]] << endl; last = query(root[pos[rt]],ll[qi],rr[qi],1,n); printf("%d\n",last); } return 0; }
相关文章推荐
- Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query (线段树)
- Educational Codeforces Round 33 (Rated for Div. 2)
- Educational Codeforces Round 33 (Rated for Div. 2)
- Educational Codeforces Round 33 (Rated for Div. 2) 题解
- Educational Codeforces Round 33 (Rated for Div. 2) D题. Credit Card(贪心)
- Educational Codeforces Round 33 (Rated for Div. 2) A题. Chess For Three
- Educational Codeforces Round 33 (Rated for Div. 2) B题. Beautiful Divisors
- 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 - Chess For Three
- Educational Codeforces Round 33 (Rated for Div. 2) B - Beautiful Divisors
- Educational Codeforces Round 33 (Rated for Div. 2) A-C题解
- Educational Codeforces Round 33 (Rated for Div. 2) C - Rumor
- Educational Codeforces Round 33 (Rated for Div. 2)A-F
- codeforces Educational Codeforces Round 33 (Rated for Div. 2)B
- Educational Codeforces Round 33 (Rated for Div. 2)A-F
- Educational Codeforces Round 33 (Rated for Div. 2) C
- Educational Codeforces Round 33 (Rated for Div. 2)【C】【并查集】
- Educational Codeforces Round 33 (Rated for Div. 2) D. Credit Card
- 【Educational Codeforces Round 48 (Rated for Div. 2) C】 Vasya And The Mushrooms