You are given a node-labeled rooted tree with n nodes.

Define the query (xk): 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 <= 105). 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 uv. 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 <= 104) which denotes the number of the queries. Each line of the next m contains two integers xk. (k <= the total node number in the subtree of x)

Output

For each query (xk), output the index of the node whose label is the k-th largest in the subtree of the node x.

Example

Input:
5
1 3 5 2 7
1 2
2 3
1 4
3 5
4
2 3
4 1
3 2
3 2 Output:
5
4
5
5

求x子树中第k大的节点。

题意:

一个以1为root的树,每次询问以x为根的子树里第k大的节点是哪个。

思路:

首先声明一下,因为是查询子树,而不是路径,这里只用到了树剖的dfs序部分,top等是没有用到的。即是这道题不需要树剖,这里写树剖这是练习!此外尝试把模板打好,方便以后参考。

  • 注意,这里的第k大是指从小到大排序的第k(不是第一次遇到这样的题了,可能是我数学不好)。
  • 题目中的“no two nodes have the same labels”应该是查询的子树里面不会出现相同的,而整棵树里面是有的(这里WA了(2^n)!次)。但是有多个的话,map又是这么映射成功的。。。。?
  • 刚刚在学树剖,于是想到了树剖,因为size[x]记录了x的子树在对应的数据结构(这里是主席树)中的左右边界。由于没有修改操作,所以可以用主席树,不然用Splay等平衡树也是可以的。这样,结合主席树对x的子树进行查询:pos=query(rt[tid[x]-1],rt[tid[x]+sz[x]-1],1,n,k)
  • 主席树的数组要开大一点。
  • 注意主席树的每一个数组和树剖的数组不要搞混了。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
map<int,int>mp;
const int maxn=;
int Laxt[maxn],Next[maxn],To[maxn];
int n,N,a[maxn],b[maxn],c[maxn];//a是原数组,b是排序数组,c是位置数组.
inline void read(int &res)
{
char chr;res=;do chr=getchar();while(chr<''||chr>'');
while(chr<=''&&chr>='') res=(res<<)+(res<<)+chr-'',chr=getchar();
}
struct Treecut_PIT
{
int sz[maxn],son[maxn],fa[maxn],dpt[maxn],cnt;
int tid[maxn],Rank[maxn],top[maxn],tim;
int rt[maxn*10],sum[maxn*10],ch[maxn*10][],tot;//主席树部分
void init()
{
mp.clear();
cnt=;tim=;tot=;//cnt对边,tim对应树剖时间,tot对应主席树
memset(Laxt,,sizeof(Laxt));
memset(son,,sizeof(son));
memset(tid,,sizeof(tid));
}
void add_edge(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
}
void dfs1(int u,int pre)
{
fa[u]=pre;dpt[u]=dpt[pre]+;sz[u]=;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i]; if(v==pre) continue;
dfs1(v,u); sz[u]+=sz[v];
if(!son[u]||sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int Top)
{
tid[u]=++tim; Rank[tim]=u; top[u]=Top;
if(!son[u]) return ;
dfs2(son[u],Top);
for(int i=Laxt[u];i;i=Next[i])
{
int v=To[i];
if(v!=son[u]&&v!=fa[u]) dfs2(v,v);
}
}
void Build(int &Now,int L,int R)
{
Now=++tot;sum[tot]=;
if(L==R) return;
int Mid=(L+R)>>;
Build(ch[Now][],L,Mid);
Build(ch[Now][],Mid+,R);
}
void insert(int &Now,int last,int L,int R,int pos)
{
Now=++tot;
ch[Now][]=ch[last][];
ch[Now][]=ch[last][];
sum[Now]=sum[last]+;
if(L==R) return;
int Mid=(L+R)>>;
if(pos<=Mid) insert(ch[Now][],ch[last][],L,Mid,pos);
else insert(ch[Now][],ch[last][],Mid+,R,pos);
}
void Make_tree()
{ for(int i=;i<=n;i++) scanf("%d",&a[i]),mp[a[i]]=i;
for(int i=;i<n;i++) {
int u,v; read(u);read(v);
add_edge(u,v); add_edge(v,u);
}
dfs1(,); dfs2(,);
for(int i=;i<=n;i++) b[i]=a[Rank[i]];
sort(b+,b+n+);N=unique(b+,b+n+)-(b+); //注意是对线段树的顺序来离散。
for(int i=;i<=n;i++) c[i]=lower_bound(b+,b+N+,a[Rank[i]])-b;//离散化 Build(rt[0],1,n);
Build(rt[],,N);
for(int i=;i<=n;i++) insert(rt[i],rt[i-],,N,c[i]);
}
int query(int ss,int tt,int L,int R,int k)
{
if(L==R) return L;
int Mid=(L+R)>>, tmp=sum[ch[tt][]]-sum[ch[ss][]];
if(k<=tmp) return query(ch[ss][],ch[tt][],L,Mid,k);
else return query(ch[ss][],ch[tt][],Mid+,R,k-tmp);
}
void Query()
{
int q,x,k; scanf("%d",&q);
while(q--){
read(x);read(k);
int pos=query(rt[tid[x]-],rt[tid[x]+sz[x]-],,n,k);
printf("%d\n",mp[b[pos]]);
}
}
}Tc;
int main()
{
while(~scanf("%d",&n)){
Tc.init();
Tc.Make_tree();
Tc.Query();
} return ;
}

SPOJ Query on a tree III (树剖(dfs序)+主席树 || Splay等平衡树)(询问点)的更多相关文章

  1. 【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 w ...

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

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

  3. 【Tyvj2133&BZOJ1146】网络管理Network(树套树,DFS序,树状数组,主席树,树上差分)

    题意:有一棵N个点的树,每个点有一个点权a[i],要求在线实现以下操作: 1:将X号点的点权修改为Y 2:查询X到Y的路径上第K大的点权 n,q<=80000 a[i]<=10^8 思路: ...

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

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

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

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

  6. 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树

    [BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...

  7. [xdoj1216]子树第k小(dfs序+主席树)

    解题关键:dfs序将树映射到区间,然后主席树求区间第k小,为模板题. #pragma comment(linker, "/STACK:1024000000,1024000000") ...

  8. BZOJ 3439: Kpm的MC密码 (trie+dfs序主席树)

    题意 略 分析 把串倒过来插进trietrietrie上, 那么一个串的kpmkpmkpm串就是这个串在trietrietrie上对应的结点的子树下面的所有字符串. 那么像 BZOJ 3551/354 ...

  9. Spoj Query on a tree III

    题目描述 给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白 有两种操作: 0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑) 1 v : 询问1到v的路径上的第一个黑点,若无,输出 ...

随机推荐

  1. urllib库利用cookie实现模拟登录慕课网

    思路 1.首先在网页中使用账户和密码名登录慕课网 2.其次再分析请求头,如下图所示,获取到请求URL,并提取出cookie信息,保存到本地 3.最后在代码中构造请求头,使用urllib.request ...

  2. Spring Ioc (this is my first example)

    一.首先看下源码结构 二.HelloWord 类 package com.northeasttycoon.bean; /** * 打印出 helloword 参数值 * * @author tycoo ...

  3. 【BZOJ4128】Matrix BSGS+hash

    [BZOJ4128]Matrix Description 给定矩阵A,B和模数p,求最小的x满足 A^x = B (mod p) Input 第一行两个整数n和p,表示矩阵的阶和模数,接下来一个n * ...

  4. 【BZOJ3991】[SDOI2015]寻宝游戏 树链的并+set

    [BZOJ3991][SDOI2015]寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩 ...

  5. WCF基础之承载服务和生成客户端

    wcf的承载有三种iis.was和自承载,它们如何承载园子里有很多,就不多赘述. 自iis7以后iis支持http和非http的协议,使用iis承载服务与其他两种承载相比,我觉的最明显的是was和自承 ...

  6. sublime 快捷键,左菜单乱码

    sublime 快捷键安装 packagecontrol https://packagecontrol.io/installation#st3 import urllib.request,os,has ...

  7. ABAP 发邮件(三)

    [转自http://blog.sina.com.cn/s/blog_7c7b16000101bnxk.html]SAP ABAP 发邮件方法三(OO) *&------------------ ...

  8. Spring AOP 学习例子

    http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example     工作忙,时间紧,不过事情再多,学习是必须的.记得以前的部门老大 ...

  9. Linux:分区

    Linux:分区 分区表 磁盘分区表主要有两种格式,一种是限制较多的 MBR 分区表,一种是较新且限制较少的 GPT 分区表. MBR MBR 中,第一个扇区最重要,里面有主要开机记录(Master ...

  10. Kindeditor 编辑区样式结构

    ke-container   ke-toolbar   ke-edit   ke-edit-iframe   ke-edit-area   ke-statusbar