题目描述

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.

输入

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)

输出

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.

样例输入

5 1 3 5 2 7 1 2 2 3 1 4 3 5 4 2 3 4 1 3 2 3 2

样例输出

5 4 5 5


题目大意

给出一棵以1为根的树,每个点有一个点权。多次询问每个点为根的子树中权值第k小的点是哪个

题解

DFS序+主席树

我也不知道为什么k-th largest number是第k小的意思。反正第k小既能解释样例又能A题。

维护一个DFS序,然后子树就转化为一段连续的区间,我们要求区间第k小。

直接裸上主席树即可。

#include <cstdio>
#include <algorithm>
#define N 100010
using namespace std;
int w[N] , s[N] , r[N] , head[N] , to[N << 1] , nxt[N << 1] , cnt , pos[N] , v[N] , last[N] , tot , root[N] , ls[N * 18] , rs[N * 18] , si[N * 18] , num;
void add(int x , int y)
{
to[++cnt] = y , nxt[cnt] = head[x] , head[x] = cnt;
}
void dfs(int x , int fa)
{
int i;
pos[x] = ++tot , v[tot] = w[x];
for(i = head[x] ; i ; i = nxt[i]) if(to[i] != fa) dfs(to[i] , x);
last[x] = tot;
}
void ins(int p , int l , int r , int x , int &y)
{
y = ++num , si[y] = si[x] + 1;
if(l == r) return;
int mid = (l + r) >> 1;
if(p <= mid) rs[y] = rs[x] , ins(p , l , mid , ls[x] , ls[y]);
else ls[y] = ls[x] , ins(p , mid + 1 , r , rs[x] , rs[y]);
}
int query(int k , int l , int r , int x , int y)
{
if(l == r) return l;
int mid = (l + r) >> 1;
if(k <= si[ls[y]] - si[ls[x]]) return query(k , l , mid , ls[x] , ls[y]);
else return query(k - si[ls[y]] + si[ls[x]] , mid + 1 , r , rs[x] , rs[y]);
}
int main()
{
int n , m , i , x , y;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &w[i]) , s[i] = w[i];
sort(s + 1 , s + n + 1);
for(i = 1 ; i <= n ; i ++ ) w[i] = lower_bound(s + 1 , s + n + 1 , w[i]) - s , r[w[i]] = i;
for(i = 1 ; i < n ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);
dfs(1 , 0);
for(i = 1 ; i <= n ; i ++ ) ins(v[i] , 1 , n , root[i - 1] , root[i]);
scanf("%d" , &m);
while(m -- ) scanf("%d%d" , &x , &y) , printf("%d\n" , r[query(y , 1 , n , root[pos[x] - 1] , root[last[x]])]);
return 0;
}

【bzoj1803】Spoj1487 Query on a tree III DFS序+主席树的更多相关文章

  1. bzoj1803: Spoj1487 Query on a tree III

    Description You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the ...

  2. 【DFS序】【莫队算法】【权值分块】bzoj1803 Spoj1487 Query on a tree III

    基本等同这个,只是询问的东西不大一样而已. http://www.cnblogs.com/autsky-jadek/p/4159897.html #include<cstdio> #inc ...

  3. 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序

    [BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...

  4. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  5. 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)

    传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...

  6. 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树

    bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...

  7. Codeforces 343D Water Tree(DFS序 + 线段树)

    题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...

  8. 【cf343】D. Water Tree(dfs序+线段树)

    传送门 题意: 给出一个以\(1\)为根的有根树,起始每个结点都为\(0\),现在有三种操作: 1.将\(v\)及\(v\)的子树都置为\(1\): 2.将\(v\)及其所有的祖先都置为\(0\): ...

  9. 【POJ3321】Apple Tree(DFS序,树状数组)

    题意:给一棵n个节点的树,每个节点开始有一个苹果,m次操作 1.将某个结点的苹果数异或 1 2.查询一棵子树内的苹果数 n,m<=100000   思路:最近一段时间在思考树上统计问题的算法 发 ...

随机推荐

  1. 2018.6.6 基于Oracle数据库的航天信息系统JDBC练习

    综合练习 一.语言和环境 A.实现语言 Java B.环境要求 JDK 6.0及其以上版本.MyEclipse7.5及其以上版本.Oracle11g.PL/SQL Developer 二.功能要求 开 ...

  2. datetime 插件

    1  写一段文本 <div id="nomarl-wrap"> <div class="form-group"> <label c ...

  3. Bootstrap 轮播(Carousel)插件

    轮播插件是一种灵活的响应式的向站点添加滑块的方式.除此之外,内容也是非常灵活的.可是图像,内嵌框架,视频或者其它您想的放置任何内容的类型. 下面是一个简单的幻灯片,使用轮播(carousel)插件显示 ...

  4. Linux命令安装vnc服务端与vnc的客户端

    第一歩:运行命令 yum install tigervnc-server -y 第二歩:安装telnet 第三歩:运行vncserver,创建桌面 vncserver -kill :1  删除桌面1的 ...

  5. SQL查询出每门课都大于80 分的学生姓名

    Course表如下: 查询出每门课都大于80 分的学生姓名有两种方法. 1.select  distinct name from Course where name not in (select di ...

  6. macbook pro开机键盘键盘和触摸板没反应问题

    今天遇到开机键盘和触摸板没反应的问题,打电话给售后,他叫我插一个usb外置键盘,开机时按shift+alt+control+电源键开机,突然发现可以了,这bug我也是醉了

  7. ES6 Reflect使用笔记

    Reflect Reflect 对象和Proxy对象一样, 为操作对象提供了新的API. 为什么使用 Reflect的方式来操作对象? 将 Object 对象上一些明显属于内部的方法放到 Reflec ...

  8. GNU C中__attribute__

    __attribute__基本介绍: 1. __attribute__ 可以设置函数属性.变量属性和类型属性. 2. __attribute__ 语法格式为:__attribute__ ((attri ...

  9. grep与正则表达式使用

    grep简介 grep 是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.通常grep有三种版本grep.egrep(等同于grep -E)和fgrep.egrep为扩展的g ...

  10. Javascript 模块化指北

    前言 随着 Web 技术的蓬勃发展和依赖的基础设施日益完善,前端领域逐渐从浏览器扩展至服务端(Node.js),桌面端(PC.Android.iOS),乃至于物联网设备(IoT),其中 JavaScr ...