[ SPOJ PT07J ] Query on a tree III
\(\\\)
Description
其实这题才是正版的 Qtree3......
给定 \(n\) 个点,以 \(1\) 号节点为根的树,点有点权。
\(m\) 次询问 以 \(x\) 为根的子树内,点权第 \(k\) 小的 节点编号 是多少。
有多组测试数据,每组数据以 \(DONE\) 结尾。
- \(n,m\le 10^5\)
\(\\\)
Solution
注意到一棵树的子树 \(DFS\) 序是连续的。
一遍 \(DFS\) 确定 \(DFS\) 序以及各个点的子树大小。
在 \(DFS\) 序上建主席树就可以了。
查子树查的其实就是 \((dfn[x]-1,dfn[x]+size[x]-1]\) 。
注意查的是点的编号,但是注意到点权两两不同,就可以离散化后记录每一个点权对应的节点编号了。
主席树注意空间 开成17倍成功RE
\(\\\)
Code
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100010
#define gc getchar
#define Rg register
#define mid ((l+r)>>1)
using namespace std;
inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
}
int n,m,tot,hd[N],val[N],tmp[N],len;
struct edge{int to,nxt;}e[N<<1];
inline void add(int u,int v){
e[++tot].to=v; e[tot].nxt=hd[u]; hd[u]=tot;
}
int cnt,dfn[N],sz[N],vpos[N],pos[N];
void dfs(int u,int fa){
sz[u]=1;
dfn[u]=++cnt;
vpos[cnt]=val[u];
for(Rg int i=hd[u],v;i;i=e[i].nxt)
if((v=e[i].to)!=fa){dfs(v,u);sz[u]+=sz[v];}
}
struct seg{
int rot[N],ptr;
inline int newnode(){return ++ptr;}
struct node{int ls,rs,sum;}c[N*20];
void build(int &rt,int l,int r){
rt=newnode();
if(l==r) return;
build(c[rt].ls,l,mid);
build(c[rt].rs,mid+1,r);
}
inline void pushup(int rt){
c[rt].sum=c[c[rt].ls].sum+c[c[rt].rs].sum;
}
void insert(int &rt,int lst,int l,int r,int x){
rt=newnode();
if(l==r){c[rt].sum=c[lst].sum+1;return;}
if(x<=mid){
c[rt].rs=c[lst].rs;
insert(c[rt].ls,c[lst].ls,l,mid,x);
}
else{
c[rt].ls=c[lst].ls;
insert(c[rt].rs,c[lst].rs,mid+1,r,x);
}
pushup(rt);
}
inline int query(int rtl,int rtr,int l,int r,int k){
if(l==r) return l;
int nowans=c[c[rtr].ls].sum-c[c[rtl].ls].sum;
if(k<=nowans) return query(c[rtl].ls,c[rtr].ls,l,mid,k);
else return query(c[rtl].rs,c[rtr].rs,mid+1,r,k-nowans);
}
}tree;
int main(){
n=rd();
for(Rg int i=1;i<=n;++i) tmp[i]=val[i]=rd();
sort(tmp+1,tmp+1+n);
for(Rg int i=1;i<=n;++i){
tmp[++len]=tmp[i];
while(tmp[i+1]==tmp[i]) ++i;
}
for(Rg int i=1;i<=n;++i){
val[i]=lower_bound(tmp+1,tmp+1+len,val[i])-tmp;
pos[val[i]]=i;
}
for(Rg int i=1,u,v;i<n;++i){
u=rd(); v=rd(); add(u,v); add(v,u);
}
dfs(1,0);
tree.build(tree.rot[0],1,len);
for(Rg int i=1;i<=n;++i) tree.insert(tree.rot[i],tree.rot[i-1],1,len,vpos[i]);
m=rd();
for(Rg int i=1,rt,k;i<=m;++i){
rt=rd(); k=rd();
printf("%d\n",pos[tree.query(tree.rot[dfn[rt]-1],tree.rot[dfn[rt]+sz[rt]-1],1,len,k)]);
}
return 0;
}
[ SPOJ PT07J ] Query on a tree III的更多相关文章
- SPOJ PT07J - Query on a tree III(划分树)
PT07J - Query on a tree III #tree You are given a node-labeled rooted tree with n nodes. Define the ...
- SP1487 PT07J - Query on a tree III (主席树)
SP1487 PT07J - Query on a tree III 题意翻译 你被给定一棵带点权的n个点的有根数,点从1到n编号. 定义查询 query(x,k): 寻找以x为根的k大点的编号(从小 ...
- SPOJ 1487 Query on a tree III(划分树)
题目链接:http://www.spoj.com/problems/PT07J/ 题意:给出一个有根树,1为根节点,每个节点有权值.若干询问,询问以u为根的子树中权值第K小的节点编号. 思路:DFS一 ...
- SP1487 PT07J - Query on a tree III 主席树+dfs序
Code: #include<iostream> #include<cstdio> #include<algorithm> #include<string&g ...
- 【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 ...
- 「SPOJ1487」Query on a tree III
「SPOJ1487」Query on a tree III 传送门 把树的 \(\text{dfs}\) 序抠出来,子树的节点的编号位于一段连续区间,然后直接上建主席树区间第 \(k\) 大即可. 参 ...
- SPOJ 375. Query on a tree (树链剖分)
Query on a tree Time Limit: 5000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Ori ...
- SPOJ QTREE Query on a tree 树链剖分+线段树
题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...
- QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树
Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...
随机推荐
- 【.Net 学习系列】-- .Net 指定时间段内定时执行的Windows服务(System.Threading.Thread)
创建一个Windows服务项目:解决方案(右击)——> 添加 ——> 新建项目——>项目类型选择Windows——>模板选择Windows服务 ,如图: 编写Windows服务 ...
- Java正则表达式过滤出字母、数字和中文
原文:http://blog.csdn.net/k21325/article/details/54090066 1.Java中过滤出字母.数字和中文的正则表达式 (1)过滤出字母的正则表达式 [^(A ...
- 007 Vlan config
sw0(config)#vlan 2 sw0(config-vlan)#name Sales sw0(config-vlan)#vlan 3 sw0(config-vlan)#name Tech sw ...
- Windows Update 的工具
Windows Update MiniTool 是一款管理 Windows Update 的工具,可以取得微軟 Windows 修補程式更新包,Windows Update 是我們用來升級系統的元件, ...
- Samba完整篇 ubuntu 10.04
基本的服务器准备工作 修改Root密码 sudo passwd root 在提示下建立新密码 修改静态IP: sudo gedit /etc/network/interfaces #网络配置文件 ...
- excel2010英文大写怎么变小写
excel大写转小写步骤如下: 1.如下图所示,若要对字母进行大.小写转换可以使用如下的步骤. 2.若要将单元格中的所有字母全部转换为大写形式,可以使用UPPER函数. 公式为 =UPPER(A2) ...
- 一个Navi过程下多个DocumentCompleted事件问题的解决的方法
7.16 Marked to Write.... 七月份马克的一篇文章了,今天才想起来把他写完,呵呵. 原本是七月份用来做微博爬虫的,后来发现新浪对机器人的检測不好绕过,连简单地訪问都会被检測出来,后 ...
- yarn之安装依赖包
安装依赖关系 yarn install用于安装项目的所有依赖项.依赖关系从您的项目package.json文件中检索,并存储在yarn.lock文件中. 开发包时,安装依赖关系最常见的是在 您刚刚检出 ...
- react 引入 百度地图API
使用 Echarts 的地图的时候,发现报错,说 Bmap api is not loaded 百度地图API没有加载 乍一想,Echarts 用的也是 百度地图 啊,没有引入百度地图,还用个啥,当然 ...
- 1.jdk安装和环境配置
这个简单,但是记不住,非要网上搜一遍不可: 1.打开我的电脑--属性--高级--环境变量 2.新建系统变量JAVA_HOME 和CLASSPATH 变量名:JAVA_HOME 变量值:C:\Progr ...