\(\\\)

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的更多相关文章

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

  2. SP1487 PT07J - Query on a tree III (主席树)

    SP1487 PT07J - Query on a tree III 题意翻译 你被给定一棵带点权的n个点的有根数,点从1到n编号. 定义查询 query(x,k): 寻找以x为根的k大点的编号(从小 ...

  3. SPOJ 1487 Query on a tree III(划分树)

    题目链接:http://www.spoj.com/problems/PT07J/ 题意:给出一个有根树,1为根节点,每个节点有权值.若干询问,询问以u为根的子树中权值第K小的节点编号. 思路:DFS一 ...

  4. SP1487 PT07J - Query on a tree III 主席树+dfs序

    Code: #include<iostream> #include<cstdio> #include<algorithm> #include<string&g ...

  5. 【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 ...

  6. 「SPOJ1487」Query on a tree III

    「SPOJ1487」Query on a tree III 传送门 把树的 \(\text{dfs}\) 序抠出来,子树的节点的编号位于一段连续区间,然后直接上建主席树区间第 \(k\) 大即可. 参 ...

  7. SPOJ 375. Query on a tree (树链剖分)

    Query on a tree Time Limit: 5000ms Memory Limit: 262144KB   This problem will be judged on SPOJ. Ori ...

  8. 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 ...

  9. QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树

    Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...

随机推荐

  1. 【.Net 学习系列】-- .Net 指定时间段内定时执行的Windows服务(System.Threading.Thread)

    创建一个Windows服务项目:解决方案(右击)——> 添加 ——> 新建项目——>项目类型选择Windows——>模板选择Windows服务 ,如图: 编写Windows服务 ...

  2. Java正则表达式过滤出字母、数字和中文

    原文:http://blog.csdn.net/k21325/article/details/54090066 1.Java中过滤出字母.数字和中文的正则表达式 (1)过滤出字母的正则表达式 [^(A ...

  3. 007 Vlan config

    sw0(config)#vlan 2 sw0(config-vlan)#name Sales sw0(config-vlan)#vlan 3 sw0(config-vlan)#name Tech sw ...

  4. Windows Update 的工具

    Windows Update MiniTool 是一款管理 Windows Update 的工具,可以取得微軟 Windows 修補程式更新包,Windows Update 是我們用來升級系統的元件, ...

  5. Samba完整篇 ubuntu 10.04

    基本的服务器准备工作 修改Root密码 sudo passwd root 在提示下建立新密码 修改静态IP: sudo gedit /etc/network/interfaces   #网络配置文件 ...

  6. excel2010英文大写怎么变小写

    excel大写转小写步骤如下: 1.如下图所示,若要对字母进行大.小写转换可以使用如下的步骤. 2.若要将单元格中的所有字母全部转换为大写形式,可以使用UPPER函数. 公式为 =UPPER(A2) ...

  7. 一个Navi过程下多个DocumentCompleted事件问题的解决的方法

    7.16 Marked to Write.... 七月份马克的一篇文章了,今天才想起来把他写完,呵呵. 原本是七月份用来做微博爬虫的,后来发现新浪对机器人的检測不好绕过,连简单地訪问都会被检測出来,后 ...

  8. yarn之安装依赖包

    安装依赖关系 yarn install用于安装项目的所有依赖项.依赖关系从您的项目package.json文件中检索,并存储在yarn.lock文件中. 开发包时,安装依赖关系最常见的是在 您刚刚检出 ...

  9. react 引入 百度地图API

    使用 Echarts 的地图的时候,发现报错,说 Bmap api is not loaded 百度地图API没有加载 乍一想,Echarts 用的也是 百度地图 啊,没有引入百度地图,还用个啥,当然 ...

  10. 1.jdk安装和环境配置

    这个简单,但是记不住,非要网上搜一遍不可: 1.打开我的电脑--属性--高级--环境变量 2.新建系统变量JAVA_HOME 和CLASSPATH 变量名:JAVA_HOME 变量值:C:\Progr ...