bzoj 1803(主席树)
来源:互联网 发布:php正则表达式语法 编辑:程序博客网 时间:2024/05/31 11:03
1803: Spoj1487 Query on a tree III
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 419 Solved: 184
[Submit][Status][Discuss]
Description
You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node whose label is k-th largest in the subtree of the node x. Assume no two nodes have the same labels.
Input
The first line contains one integer n (1 <= n <= 10^5). The next line contains n integers li (0 <= li <= 109) which denotes the label of the i-th node. Each line of the following n - 1 lines contains two integers u, v. They denote there is an edge between node u and node v. Node 1 is the root of the tree. The next line contains one integer m (1 <= m <= 10^4) which denotes the number of the queries. Each line of the next m contains two integers x, k. (k <= the total node number in the subtree of x)
Output
For each query (x, k), output the index of the node whose label is the k-th largest in the subtree of the node x.
Sample Input
5
1 3 5 2 7
1 2
2 3
1 4
3 5
4
2 3
4 1
3 2
3 2
1 3 5 2 7
1 2
2 3
1 4
3 5
4
2 3
4 1
3 2
3 2
Sample Output
5
4
5
5
解题思路:首先dfs求出dfs序列,然后就将树的数据化到序列上了,然后在序列上找K大,明显主席树。然而输出有点奇怪,输出的是值所对应得点,那只要多储存一个值,
就是到第i棵线段树,保存更改的最小面的那个值所对应的最后面的对应得点。
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#define rep(i,j,k) for(int i = j; i <= k; i++)#define MAX 200009#define u 18using namespace std;int to[1 * MAX], next[1 * MAX], head[1 * MAX], a[MAX], c[MAX];int n, m, k, dfn[MAX * 1], tree[u * MAX], child[u * MAX][2], size[u * MAX];int tot = 0, DfsClock = 0, sum = 0, first[MAX * 1], last[1 * MAX], num = 0;inline void add (int x, int y){ to[++tot] = y; next[tot] = head[x]; head[x] = tot;}void dfs (int x, int fa){ dfn[first[x] = ++DfsClock] = x; for (int i = head[x]; i; i = next[i]) if (to[i] != fa) dfs (to[i], x); dfn[last[x] = ++DfsClock] = x;}inline int add (int l, int r, int pos, int root){ int New = ++sum, mid = (l + r) >> 1; size[New] = size[root] + 1; if (l == r) return New; if (pos <= mid) child[New][0] = add (l, mid, pos, child[root][0]), child[New][1] = child[root][1]; else child[New][0] = child[root][0], child[New][1] = add (mid + 1, r, pos, child[root][1]); return New;}struct wbysr{ int value, id;}e[MAX];bool cmp (wbysr a1, wbysr a2){ return a1.value < a2.value;}int main(){ scanf ("%d", &n); rep (i, 1, n) scanf ("%d", &a[i]), e[i].value = a[i], e[i].id = i; sort (e + 1, e + 1 + n, cmp); e[0].value = e[1].value - 90; rep (i, 1, n) if (e[i].value != e[i-1].value) c[++num] = e[i].value; rep (i, 1, n - 1) { int a1, a2; scanf ("%d%d", &a1, &a2); add (a1, a2); add (a2, a1); } dfs (1,0); tree[0] = 0; size[0] = 0; rep (i, 1, DfsClock) tree[i] = add (1, num, lower_bound (c + 1, c + 1 + num, a[dfn[i]]) - c, tree[i - 1]); scanf ("%d", &m); while (m--) { int x; scanf ("%d%d", &x, &k); k *= 2; int t0 = tree[first[x] - 1], t1 = tree[last[x]]; int l = 1, r = num; while (l <= r) { int now = size[child[t1][0]] - size[child[t0][0]]; int mid = (l + r) >> 1; if (k <= now) t0 = child[t0][0], t1 = child[t1][0], r = mid; else t0 = child[t0][1], t1 = child[t1][1], k -= now, l = mid + 1; } printf ("%d\n", e[r].id); } return 0;}
0 0
- bzoj 1803(主席树)
- bzoj 1803(DFS序+主席树)
- Bzoj 1803 spoj qtree3 主席树
- bzoj 1803(主席树+dfs序)
- bzoj 1878(莫队)(主席树)
- Bzoj 2653 middle(二分+主席树)
- bzoj 3524: [Poi2014]Couriers(主席树)
- bzoj 2653: middle (二分+主席树)
- BZOJ 4448 主席树+树链剖分(在线)
- bzoj 3207(主席树+hash)
- bzoj 2653(主席树+二分)
- bzoj 3123(主席树+启发式合并)
- bzoj 3524(主席树+二分)
- bzoj 3932(主席树)
- BZOJ 2588 主席树
- 【BZOJ 2809】dispatching(主席树)
- 【主席树】 BZOJ 2653 middle
- 【主席树】BZOJ 2653 middle
- ZooKeeper 笔记(2) 监听数据变化
- java-swing-皮肤
- php中使用exec,system等函数调用系统命令
- Android学习笔记(一)
- Java IO详解
- bzoj 1803(主席树)
- ClassLoader:类加载详解
- Android开发系列(十一):对手机通讯录的读取、添加、删除、查找
- pat 1067 Sort with Swap(0,*) (25)
- 回归假设
- 文件的创建
- IPC机制之使用ContentProvider
- thinkphp自定义模板标签(一)
- SGI STL的空间配置器alloc