主席树的入门题目,这道题的题意其实就是说,给你一棵树,询问在两个节点之间的路径上的区间第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小的更多相关文章

  1. spoj COT - Count on a tree (树上第K小 LCA+主席树)

    链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...

  2. Count on a tree 树上主席树

    Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...

  3. Count on a tree 树上区间第K小

    Count on a tree 题意:求路径 u到v上的 第k小的权重. 题解:先DFS建数, 然后对于每个节点往上跑出一颗主席树, 然后每次更新. 查询的时候, u, v, k, 找到  z = l ...

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

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

  6. Count on a tree(树上路径第K小)

    题目链接:https://www.spoj.com/problems/COT/en/ 题意:求树上A,B两点路径上第K小的数 思路:主席树实际上是维护的一个前缀和,而前缀和不一定要出现在一个线性表上. ...

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

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

  9. 树上第k小,可持久化线段树+倍增lca

    给定一颗树,树的每个结点都有权值, 有q个询问,每个询问是 u v k ,表示u到v路径上第k小的权值是多少. 每个结点所表示的线段树,是父亲结点的线段树添加该结点的权值之后形成的新的线段树 c[ro ...

随机推荐

  1. JAVA邀请码生成器

    code import java.util.Random; /** * 邀请码生成器,算法原理:<br/> * 1) 获取id: 1127738 <br/> * 2) 使用自定 ...

  2. IIS 配置问题

    1 IIS错误需要重新运行配置 重新注册.netframework. 解决方式:cmd   C:\Windows\Microsoft.NET\Framework\v4.0.30319 aspnet_r ...

  3. caffe 的docker安装过程及相关linux操作总结

    一.caffe 和 docker的安装编译 docker pull caffe镜像(注意使用docker安装省去安装CUDA和cudnn的安装.) 安装相关依赖包 安装opencv3(使用源码安装) ...

  4. centos7默认安装没有连接网络

    1.显示所有连接 #nmcli con show 2.连接网络 #nmcli con up ens33 这个ens33是通过第一步查到的 /etc/sysconfig/network-scripts目 ...

  5. Linux下备份Mysql所有数据库

    需求:备份除了mysql系统数据库的所有数据库 以下为Shell脚本,只需要修改用户密码即可 MYSQL_USER=root MYSQL_PASS=123456 MYSQL_CONN="-u ...

  6. 使用DIV+CSS布局网站的优点和缺陷

    随着WEB2.0标准化设计理念的普及,国内很多大型门户网站已经纷纷采用DIV+CSS制作方法,从实际应用情况来看,此种方法绝对好于表格制作页面的方法. 如今大部分网站仍然采用表格嵌套内容的方式来制作网 ...

  7. JavaScript--函数中this的几种指向

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 视觉暂留-Info:这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝!

    ylbtech-视觉暂留-Info:这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝! 1.返回顶部 1. 这些神奇的“视觉暂留”动画,每一幅都让人拍案叫绝! 原创|发布:2018-05-28 19: ...

  9. Auto reloading enabled

    在eclipse中集成tomcat来开发时, 如果使用run as模式启动项目的话,tomcat配置Auto reloading enabled,我们修改java文件,项目会重新加载,修改的内容会生效 ...

  10. 笔记:OSAL st 宏学习 do { x } while (__LINE__ == -1)

    笔记:OSAL st 宏学习 do { x } while (LINE == -1) #define st(x) do { x } while (__LINE__ == -1) 这段的意思是让代码可以 ...