题目描述

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. 关于java的自增问题

    程序执行结果是0,,,因为count永远是0

  2. java连接MySQL数据库操作步骤

    package com.swift; //这里导入的包是java.sql.Connection而不是com.mysql.jdbc.Connection import java.sql.Connecti ...

  3. Express session的使用

    进行session存储时需引用中间件,app.js var express=require('express'); var app=express(); var cookieParser = requ ...

  4. OI,我的决心

    虽然从初一就开始NOIP,但沉溺于游戏编程等各种乱七八糟的技术,一直没对算法有过透彻的研究. ——————————简单的来说就是水过了—————————— 我生于一个弱省,就读于一所弱校(我们全区的都 ...

  5. 洛谷P1111修复公路并查集改

    看了他们的题解感觉很震惊,为什么要用kruskal,这题要用到最小生成树吗??? 38行短短的程序就可以了,我觉得学习不是一种套用,套自己学的,而且题解很大一部分都是kruskal. 个人认为自己的程 ...

  6. .net core 获取浏览器UserAgent

    这两天由于自己公司的机器磁盘不够用了,果断把VS2015卸载了,只留下VS2017 当我打开一个以前一个很简单的MVC4.0的项目时候 温馨提示要安装MVC4,我犹豫了一下,还是点了安装,接下来提示要 ...

  7. 科学计算库Numpy——排序

    矩阵按维度排序 使用np.sort()进行排序. 排序索引值 使用np.argsort()排序,返回排序后的索引值. 备注:array1[1,2]=1.2,array1[1,0]=5.6,array1 ...

  8. Uva:11401-Triangle Counting

    Triangle Counting Time limit1000 ms Description You are given n rods of length 1, 2-, n. You have to ...

  9. 动态规划:HDU1224-Free DIY Tour

       Free DIY Tour Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  10. (ADO.NET)SqlCommand参数化查询

    string strcon = "Persist Security Info=False;User id=sa;pwd=lovemary;database=student;server=(l ...