E - Count on a tree 树上第K小
主席树的入门题目,这道题的题意其实就是说,给你一棵树,询问在两个节点之间的路径上的区间第K小
我们如何把树上问题转换为区间问题呢?
其实DFS就可以,我们按照DFS的顺序,对线段树进行建树,那么这个树上问题就可以转换为区间问题了,
那么如何询问来表示两个节点之间的路径呢?
其实也很简单,可以看看以下的图。。。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#define LL long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=j;i>=k;i--)
#define pb push_back
using namespace std;
const int maxx = ;
struct node{
int l,r,cnt;
}tree[maxx*];
inline int MID(int l,int r){return (l+r)>>;};
int root[maxx*];
int a[maxx];
int ver[maxx*],Next[maxx*],head[maxx];
int tot,cnt,n,m;
int t=;
int fa[maxx],p[maxx][],deepth[maxx];
vector<int>v;
void add(int x,int y){
ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
ver[++tot]=x;Next[tot]=head[y];head[y]=tot;
}
void update(int l,int r,int pre,int &now,int pos){
now=++cnt;
tree[now]=tree[pre];
tree[now].cnt++;
if (l==r)return;
int mid=(l+r)>>;
if (pos<=mid)
update(l,mid,tree[pre].l,tree[now].l,pos);
else
update(mid+,r,tree[pre].r,tree[now].r,pos);
}
int query(int l,int r,int L,int R,int k,int lca,int flac){
if (l==r)return l;
int tmp=tree[tree[R].l].cnt+tree[tree[L].l].cnt-tree[tree[lca].l].cnt-tree[tree[flac].l].cnt;
int mid=MID(l,r);
if (k<=tmp)
return query(l,mid,tree[L].l,tree[R].l,k,tree[lca].l,tree[flac].l);
else
return query(mid+,r,tree[L].r,tree[R].r,k-tmp,tree[lca].r,tree[flac].r);
}
void dfs(int u,int pre){
fa[u]=pre;
deepth[u]=deepth[pre]+;
p[u][]=pre;
update(,n,root[pre],root[u],a[u]);
rep(i,,)p[u][i]=p[p[u][i-]][i-];
for (int i=head[u];i;i=Next[i]){
int y=ver[i];
if (y==pre)continue;
dfs(y,u);
}
}
int LCA(int x,int y){
if (deepth[x]>deepth[y])swap(x,y);
per(i,t,){
if (deepth[p[y][i]]>=deepth[x])y=p[y][i];
}
if (x==y)return y;
per(i,t,){
if(p[x][i]!=p[y][i])x=p[x][i],y=p[y][i];
}
return p[x][];
}
int main(){
while(~scanf("%d%d",&n,&m)){
int uu,vv;
memset(head,,sizeof(head));
rep(i,,n){
scanf("%d",&a[i]);
v.pb(a[i]);
}
tot=;
cnt=;
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
rep(i,,n-){
scanf("%d%d",&uu,&vv);
add(uu,vv);
}
rep(i,,n){
a[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin()+;
}
dfs(,);
int k;
while(m--){
scanf("%d%d%d",&uu,&vv,&k);
int lca=LCA(uu,vv);
printf("%d\n",v[query(,n,root[uu],root[vv],k,root[lca],root[fa[lca]])-]);
}
}
return ;
}
E - Count on a tree 树上第K小的更多相关文章
- spoj COT - Count on a tree (树上第K小 LCA+主席树)
链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...
- Count on a tree 树上主席树
Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...
- Count on a tree 树上区间第K小
Count on a tree 题意:求路径 u到v上的 第k小的权重. 题解:先DFS建数, 然后对于每个节点往上跑出一颗主席树, 然后每次更新. 查询的时候, u, v, k, 找到 z = l ...
- SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)
COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...
- SPOJ 10628 Count on a tree(Tarjan离线 | RMQ-ST在线求LCA+主席树求树上第K小)
COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...
- Count on a tree(树上路径第K小)
题目链接:https://www.spoj.com/problems/COT/en/ 题意:求树上A,B两点路径上第K小的数 思路:主席树实际上是维护的一个前缀和,而前缀和不一定要出现在一个线性表上. ...
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树
2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...
- 树上第k小,可持久化线段树+倍增lca
给定一颗树,树的每个结点都有权值, 有q个询问,每个询问是 u v k ,表示u到v路径上第k小的权值是多少. 每个结点所表示的线段树,是父亲结点的线段树添加该结点的权值之后形成的新的线段树 c[ro ...
随机推荐
- 2019-3-1-WPF-从零开始开发-dotnet-Remoting-程序
title author date CreateTime categories WPF 从零开始开发 dotnet Remoting 程序 lindexi 2019-03-01 09:30:45 +0 ...
- 洛谷P2073 送花 [2017年6月计划 线段树01]
P2073 送花 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花 ...
- sending data mysql slow Mysql查询非常慢的可能原因
1.用explain看看mysql的执行情况,可以得知,task_id扫描了近20万条数据,而且这个task_id不是索引 2.为这个task_id所在的表,将此字段添加索引后,查询就变得很快了
- PHP 学习1.3
1.展示类的继承和静态的方法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "htt ...
- js里面的this指向
1. this是动态绑定的,或者说是在代码运行期绑定而不是在书写期 function fire () { console.log(this.a) } var obj = { a: 1, fire: ...
- hdu 4512 (LCIS)
好久没写解题报告了,最近几周好忙...感觉是我进大学以来最忙的一段时间了,要给新生准备下周三比赛的题目,下周五要去南京赛区,回来之后马上就要期中考试了...不想挂科 额,很早之前就看过关于LCIS ...
- 从0开始学习 GitHub 系列之「01.初识 GitHub
转载:http://blog.csdn.net/googdev/article/details/52787516 1. 写在前面 我一直认为 GitHub 是程序员必备技能,程序员应该没有不知道 Gi ...
- python之高阶函数--map()和reduce()
以下为学习笔记:来自廖雪峰的官方网站 1.高阶函数:简单来说是一个函数里面嵌入另一个函数 2.python内建的了map()和reduce()函数 map()函数接收两参数,一个是函数,一个是Iter ...
- Docker.[3].镜像操作.
Docker.[3].镜像操作. 熟悉基础指令: 查看本地镜像 docker images 查看本地镜像 docker image list (和上面显示的结果一样.) 删除本地镜像 docker r ...
- Leetcode703.Kth Largest Element in a Stream数据流中的第K大元素
设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中 ...