[SPOJ-PT07J] Query on tree III (主席树)
题意翻译
你被给定一棵带点权的n个点的有根数,点从1到n编号。
定义查询 query(x,k): 寻找以x为根的k大点的编号(从小到大排序第k个点)
假设没有两个相同的点权。
输入格式: 第一行为整数n,第二行为点权,接下来n-1行为树边,接下来一行为整数m,下面m行为两个整数x,k,代表query(x,k)
输出格式: m行,输出每次查询的结果。
Translated by @vegacx
题目描述
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}5 ). The next line contains n integers _l {i}i (0 <= _l {i}i <= 10 ^{9}9 ) 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}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.
输入输出样例
输入样例#1:
5
1 3 5 2 7
1 2
2 3
1 4
3 5
4
2 3
4 1
3 2
3 2
输出样例#1:
5
4
5
5
Solution
这道题,直接维护一遍树上的DFS序,然后记录每个节点 siz,再用主席树维护即可。
然后查询的时候查询 ( b[i] , b[i]+siz[i]-1 ) ,需要注意的是输出的是编号。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
struct sj{int to,next;}line[maxn*2];
int size,n,m,num,q,siz[maxn];
int head[maxn],id[maxn],tot,idx[maxn];
int a[maxn],b[maxn],c[maxn],T[maxn];
int L[maxn*20],R[maxn*20],sum[maxn*20];
void add(int x,int y)
{
line[++size].to=y;
line[size].next=head[x];
head[x]=size;
}
int old[maxn];
void dfs(int x)
{
siz[x]=1;
a[++num]=c[x];
id[x]=num; b[num]=a[num];
old[num]=x;
for(int i=head[x];i;i=line[i].next)
{
int tt=line[i].to;
if(!siz[tt])
{
dfs(tt);
siz[x]+=siz[tt];
}
}
}
int build(int l,int r)
{
int rt=++tot;
if(l!=r)
{
int mid=(l+r)/2;
L[rt]=build(l,mid);
R[rt]=build(mid+1,r);
}
return rt;
}
int update(int pre,int l,int r,int x)
{
int rt=++tot;
L[rt]=L[pre];
R[rt]=R[pre];
sum[rt]=sum[pre]+1;
int mid=(l+r)/2;
if(l!=r)
{
if (x<=mid) L[rt]=update(L[pre],l,mid,x);
else R[rt]=update(R[pre],mid+1,r,x);
}
return rt;
}
int query(int x,int y,int l,int r,int k)
{
if(l==r)return l;
int now=sum[L[y]]-sum[L[x]];
int mid=(l+r)/2;
if(now>=k) return query(L[x],L[y],l,mid,k);
else return query(R[x],R[y],mid+1,r,k-now);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
for(int i=1;i<n;i++)
{
int x,y; scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
dfs(1);
sort(b+1,b+1+n);
m=unique(b+1,b+1+n)-b-1;
T[0]=build(1,m);
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(b+1,b+1+m,a[i])-b,
T[i]=update(T[i-1],1,m,a[i]);
idx[a[i]]=old[i];
}
scanf("%d",&q);
while(q--)
{
int x,k;
scanf("%d%d",&x,&k);
int p=query(T[id[x]-1],T[id[x]+siz[x]-1],1,m,k);
printf("%d\n",idx[p]);
}
}
/*
5
1 3 5 2 7
1 2
2 3
1 4
3 5
4
2 3
4 1
3 2
3 2
*/
[SPOJ-PT07J] Query on tree III (主席树)的更多相关文章
- SP1487 PT07J - Query on a tree III (主席树)
SP1487 PT07J - Query on a tree III 题意翻译 你被给定一棵带点权的n个点的有根数,点从1到n编号. 定义查询 query(x,k): 寻找以x为根的k大点的编号(从小 ...
- 【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 ...
- BZOJ1803Spoj1487 Query on a tree III——主席树
题目大意 给一棵有点权的n个点的有根树,保证任意两点的点权不同,m次询问每次询问x的子树中权值第k大的点. 输入 先输入n,然后每个点点权,再输入n-1行每行两个数x,y代表x和y相连,再输入m,之后 ...
- bzoj 1803: Spoj1487 Query on a tree III(主席树)
题意 你被给定一棵带点权的n个点的有根数,点从1到n编号. 定义查询 query(x,k): 寻找以x为根的k大点的编号(从小到大排序第k个点) 假设没有两个相同的点权. 输入格式: 第一行为整数n, ...
- SP1487 PT07J - Query on a tree III 主席树+dfs序
Code: #include<iostream> #include<cstdio> #include<algorithm> #include<string&g ...
- BZOJ_1803_Spoj1487 Query on a tree III_主席树+dfs序
BZOJ_1803_Spoj1487 Query on a tree III_主席树 Description You are given a node-labeled rooted tree with ...
- 【BZOJ2588】Count On a Tree(主席树)
[BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...
- Count on a tree 树上主席树
Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...
- 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 ...
随机推荐
- Bootstrap历练实例:堆叠的进度条
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- Java基础面试操作题:线程同步代码块 两个客户往一个银行存钱,每人存三十次一次存一百。 模拟银行存钱功能,时时银行现金数。
package com.swift; public class Bank_Customer_Test { public static void main(String[] args) { /* * 两 ...
- VS快捷键总结(开发中经常遇到)
1.窗口快捷键 (大家有没有发现但凡跟窗口挂上钩的快捷键当中都有一个W,那是因为W代表Windows也就是窗口的意思) Ctrl+W,W: 浏览器窗口 (浏览橱窗用有道的翻译是window shop ...
- C++ 学习笔记(五)类的知识小结一(重载,友元函数,静态成员,new)
---恢复内容开始--- 学习C++类知识点还是挺多的,每个知识点学习的时候都觉得这个知识点咋那么多东西,其实真学完了再回头看好像也就那么点.这次用程序写一个黑猫揍白猫的故事总结一下这段时间学习的零碎 ...
- centos启动流程
centos6启动流程 1.主板,post加电自检,检查硬件环境 2.主板选择一个硬盘进行引导,执行mbr446 grub stage1 3.grub stage1.5 加载/boot分区文件系统驱动 ...
- 一个4年工作经验的java程序员的困惑,怎样才能能为一个架构师,请教大神
一个4年工作经验的java程序员的困惑,怎样才能能为一个架构师 LZ本人想往架构师发展, 业余时间也会看一些书籍, 但是感觉没有头绪, 有些书看了,也没有地方实践 我做了4年的java开发, 在一个公 ...
- sphinx 快速使用
建立配置文件 例可以参照之前的模板新建一个配置文件 sphinx/etc目录 #MySQL数据源配置,详情请查看:http://www.coreseek.cn/products-install/mys ...
- Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery)
Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery) 体验 冒号搜索 1. 获取谷歌搜索api 谷歌搜索api教程 2. 后台调用 程序入口 main.go // ...
- mysql主主复制汇总整理
mysql主主复制汇总整理 一.Mysql主主.主从复制主要思路: 1.mysql复制实质: 就是其他的MySQL数据库服务器将这个数据变更的二进制日志在本机上再执行一遍,因此非常重要的一点是mysq ...
- Maven配置项目依赖使用本地仓库的方法汇总
Maven配置项目使用本地仓库有以下方式实现: 1.类似本地仓库,但是属于本地依赖,比如某个JAR包是引用第三方的,直接放在了项目的lib文件夹,那么此时可以如下配置项目的POM: <depen ...