SP1487 PT07J - Query on a 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序来建立主席树,也正因如此,所以我们在dfs的过程中要重新赋一下值,给当前dfs序为i的节点另开两个存值的数组,一个是原数组,一个离散数组,这样值才能与主席树对上号


void dfs(int u,int fa) {
id[u]=++cnt, a[cnt]=b[cnt]=w[u], inv[cnt]=u, size[u]=1;//inv[]存的是通过dfs序找到节点
for (int i=head[u];i;i=nex[i]) {
if (to[i]==fa) continue;
dfs(to[i],u); size[u]+=size[to[i]];
}
}

在加入节点的过程中,因为题目问的是节点编号而不是值,我们还要把当前值赋为节点编号

至于查询,就是以dfs序和子树大小来查,因为是连续的...

其实如果会静态主席树,这道题稍微难一点的主要还是建树,会建树就会查询了

Code

#include<bits/stdc++.h>
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define rg register
#define mid ((l+r)>>1)
#define in(i) (i=read())
using namespace std; const int N=1e5+10; int read() {
int ans=0,f=1; char i=getchar();
while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar();
return ans*=f;
} int T,n,m,tot,cur,cnt;
int w[N],a[N],b[N],id[N],inv[N],size[N],ans[N];
int to[N<<1],nex[N<<1],head[N];
int rt[N<<5],lc[N<<5],rc[N<<5],sum[N<<5]; void add(int a,int b) {
to[++cur]=b,nex[cur]=head[a],head[a]=cur;
to[++cur]=a,nex[cur]=head[b],head[b]=cur;
} void build(int &u,int l,int r) {
u=++tot,sum[u]=0;
if (l==r) return;
build(lc[u],l,mid);
build(rc[u],mid+1,r);
} void update(int &u,int l,int r,int pre,int x) {
u=++tot;
sum[u]=sum[pre]+1,lc[u]=lc[pre],rc[u]=rc[pre];
if (l==r) return;
if(x<=mid) update(lc[u],l,mid,lc[pre],x);
else update(rc[u],mid+1,r,rc[pre],x);
} int query(int u,int v,int l,int r,int k) {
if(l==r) return ans[l];
int rest=sum[lc[v]]-sum[lc[u]];
if(k<=rest) return query(lc[u],lc[v],l,mid,k);
else return query(rc[u],rc[v],mid+1,r,k-rest);
} void dfs(int u,int fa) {
id[u]=++cnt, a[cnt]=b[cnt]=w[u], inv[cnt]=u, size[u]=1;
for (int i=head[u];i;i=nex[i]) {
if (to[i]==fa) continue;
dfs(to[i],u); size[u]+=size[to[i]];
}
} int main()
{
in(n);
for (int i=1;i<=n;i++) in(w[i]);
for (int i=1,x,y;i<n;i++) in(x), in(y), add(x,y);
dfs(1,0);
sort(b+1,b+1+n); build(rt[0],1,n);
for (int i=1;i<=n;i++) {
a[i]=lower_bound(b+1,b+1+n,a[i])-b;
ans[a[i]]=inv[i];
update(rt[i],1,n,rt[i-1],a[i]);
}
in(m);
for (int i=1,x,k;i<=m;i++) {
in(x), in(k);
printf("%d\n",query(rt[id[x]-1],rt[id[x]+size[x]-1],1,n,k));
}
}

SP1487 PT07J - Query on a tree III (主席树)的更多相关文章

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

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

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

  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. BZOJ1803Spoj1487 Query on a tree III——主席树

    题目大意 给一棵有点权的n个点的有根树,保证任意两点的点权不同,m次询问每次询问x的子树中权值第k大的点. 输入 先输入n,然后每个点点权,再输入n-1行每行两个数x,y代表x和y相连,再输入m,之后 ...

  5. bzoj 1803: Spoj1487 Query on a tree III(主席树)

    题意 你被给定一棵带点权的n个点的有根数,点从1到n编号. 定义查询 query(x,k): 寻找以x为根的k大点的编号(从小到大排序第k个点) 假设没有两个相同的点权. 输入格式: 第一行为整数n, ...

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

  7. [SPOJ-PT07J] Query on tree III (主席树)

    题意翻译 你被给定一棵带点权的n个点的有根数,点从1到n编号. 定义查询 query(x,k): 寻找以x为根的k大点的编号(从小到大排序第k个点) 假设没有两个相同的点权. 输入格式: 第一行为整数 ...

  8. [ SPOJ PT07J ] Query on a tree III

    \(\\\) Description 其实这题才是正版的 Qtree3...... 给定 \(n\) 个点,以 \(1\) 号节点为根的树,点有点权. \(m\) 次询问 以 \(x\) 为根的子树内 ...

  9. 「SPOJ1487」Query on a tree III

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

随机推荐

  1. gopherjs

    An example implementation of a GopherJS client and a Go server using the Improbable gRPC-Web impleme ...

  2. 【win10系统问题】远程桌面登录一次后,第二次登录看不到用户名和密码输入框

    [win10系统远程桌面登录问题] 远程桌面登录某服务器一次后,第二次登录看不到用户名和密码输入框 [解决方法] 在注册表里找到该路径下的远程服务器ip,删除即可: HKEY_CURRENT_USER ...

  3. USACO 2.3.4 Money Systems 货币系统(完全背包)

    Description 母牛们不但创建了他们自己的政府而且选择了建立了自己的货币系统. [In their own rebellious way],,他们对货币的数值感到好奇. 传统地,一个货币系统是 ...

  4. Scrum立会报告+燃尽图(十一月十九日总第二十七次):功能开发与修复上一阶段bug

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...

  5. Scrum立会报告+燃尽图(十月十五日总第六次):视频上传及选题介绍工作

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2196 Scrum立会master:田良 一.小组介绍 组长:付佳 组员: ...

  6. Linux 下web开发环境搭建-jdk环境搭建

    Centos 7 附:windows 下jdk环境变量 CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools ...

  7. 栈和队列在python中的实现

    栈和队列是两种基本的数据结构,同为容器类型.两者根本的区别在于: stack:后进先出 queue:先进先出 PS:stack和queue是不能通过查询具体某一个位置的元素而进行操作的.但是他们的排列 ...

  8. Markdown使用github风格时报TLS错误解决办法

    https://docs.microsoft.com/en-us/officeonlineserver/enable-tls-1-1-and-tls-1-2-support-in-office-onl ...

  9. Splash广告界面

    在软件开始启动时都是会使用一个splashActivity实现联网判断和相关资源的加载,在一款网络软件上开始时的缓存加载和网络判断可以为用户节省不必要的流量开销. 使用handler延时启动下一个ac ...

  10. ajax跨域问题(三种解决方案)

    为什么会出现跨域 跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问.也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其 ...