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 ...
随机推荐
- hdu 1296 Polynomial Problem(多项式模拟)
Problem Description We have learned how to obtain the value of a polynomial when we were a middle sc ...
- ssdb常用知识点
ssdb备份与恢复 http://ssdb.io/docs/zh_cn/backup.html ssdb注意事项 建议将logger.level设置为 debug 级别. 配置文件 deny,allo ...
- mybatis中使用包装对象
在实际的应用中,很多时候我们需要的查询条件都是一个综合的查询条件,因此我们需要对已经存在的实体进行再一次的包装,以方便我们进行查询操作,于是包装对象的作用就很明显了,在这里我举一个简单的例子 1.首先 ...
- 2019阿里云开年Hi购季域名与商标分会场全攻略!
2019阿里云云上Hi购季活动已经于2月25日正式开启,从已开放的活动页面来看,活动分为三个阶段: 2月25日-3月04日的活动报名阶段.3月04日-3月16日的新购满返+5折抢购阶段.3月16日-3 ...
- json原生解析
身为新手,在运用网络解析json数据的时候,发现先会用Gson等框架解析json,然后就懒起来学原生解析了,这下在看别人写的demo的时候就尴尬了,一块块的,不懂写什么,气氛十分尴尬. 不多说,先来条 ...
- WPF DrawingVisual详解
在WPF中,如果需要绘制大量图形元素,并且对性能要求严苛的话,最好使用DrawingVisual,当然,你也可以选用 Path类和比Path类更轻量级的Geometry(几何形状)来实现你的需求,但是 ...
- scala/java读取项目中的文件
一.获取jar包的位置 1.使用类路径 String path = this.getClass().getProtectionDomain().getCodeSource().getLocation( ...
- 2019.11.12htmlhomework1
ex: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- Directx11教程(59) tessellation学习(1)
原文:Directx11教程(59) tessellation学习(1) 在D3D11管线中,新增加了3个stage, Hull shader, Tessellator, Domain s ...
- ImmutableMap不可使用null的问题
示例 在项目中有发现类似下方的代码, Map tmpParams = ImmutableMap.of( "extraInfos", ext.get("extraInfos ...