【bzoj1803】Spoj1487 Query on a tree III DFS序+主席树
题目描述
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序+主席树的更多相关文章
- 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 ...
- 【DFS序】【莫队算法】【权值分块】bzoj1803 Spoj1487 Query on a tree III
基本等同这个,只是询问的东西不大一样而已. http://www.cnblogs.com/autsky-jadek/p/4159897.html #include<cstdio> #inc ...
- 【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 ...
- dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
4448: [Scoi2015]情报传递 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 588 Solved: 308[Submit][Status ...
- 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)
传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...
- 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树
bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- 【cf343】D. Water Tree(dfs序+线段树)
传送门 题意: 给出一个以\(1\)为根的有根树,起始每个结点都为\(0\),现在有三种操作: 1.将\(v\)及\(v\)的子树都置为\(1\): 2.将\(v\)及其所有的祖先都置为\(0\): ...
- 【POJ3321】Apple Tree(DFS序,树状数组)
题意:给一棵n个节点的树,每个节点开始有一个苹果,m次操作 1.将某个结点的苹果数异或 1 2.查询一棵子树内的苹果数 n,m<=100000 思路:最近一段时间在思考树上统计问题的算法 发 ...
随机推荐
- 将数据库数据显示到TreeView控件中
实现效果: 知识运用: TreeView控件中的Nodes集合的Add方法 实现代码: private void init() { treeView1.ShowLines = true; treeVi ...
- 2018.5.27 OraclePLSQL编程 if-else练习和循环结构练习
if-else运用 declare v_num number(8); begin v_num :=&n; if v_num>0 and v_num<100 then dbms_ou ...
- pytho线程信号量
pytho线程信号量 import threading,time def going(num,sleep_time): semaphore.acquire()#启动允许执行 print("g ...
- idea右侧的工具栏不见,包括maven以及其他
通用,设置后右侧工具栏可见 可以通过view-->windows tool看到maven的
- 3- vue django restful framework 打造生鲜超市 - model设计和资源导入
3- vue django restful framework 打造生鲜超市 - model设计和资源导入 使用Python3.6与Django2.0.2(Django-rest-framework) ...
- 同时启动多个tomcat的配置信息
同时启动多个tomcat的配置信息 下面把该配置文件中各端口的含义说明下. <Server port="8005" shutdown="SHUTDOWN" ...
- python从入门到精通之30天快速学python视频教程
点击了解更多Python课程>>> python从入门到精通之30天快速学python视频教程 课程目录: python入门教程-1-Python编程语言历史及特性.mkv pyth ...
- 快速搭建FTP服务
Linux下ftp服务可以通过搭建vsftpd服务来实现,以CentOS为例,首先查看系统中是否安装了vsftpd,可以通过执行命令 rpm -qa | grep vsftpd 来查看是否安装相应的包 ...
- Python中的dict
dict_lst = [ ('字典的键必须可哈希',), ('字典的键重复覆盖',), ('字典可迭代') ('增',), ('删',), ('改',), ('查',), ('练习',), ] 字典的 ...
- BFS:HDU-1072-Nightmare
Nightmare Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...