Count on a tree

题意:求路径 u到v上的 第k小的权重。

题解:先DFS建数, 然后对于每个节点往上跑出一颗主席树, 然后每次更新。 查询的时候, u, v, k, 找到  z = lca(u,v) , p = anc[z][0], 然后对于这条路上左边子节点的个数就可以被表示为u,v的树- z,p的树上的值。

然后主要是LCA不怎么用写搓了, 找了好久的bug。 汗。

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
const int M = 5e6 + ;
vector<int> son[N];
int lson[M], rson[M], cnt[M];
int anc[N][];
int tot, t;
int a[N], w[N], deep[N], root[N];
int id(int x){
return lower_bound(a+, a++t, x) - a;
}
int Build(int l, int r){
int now = ++tot;
cnt[now] = ;
if(l < r){
int m = l+r >> ;
lson[now] = Build(l, m);
rson[now] = Build(m+, r);
}
return now;
}
int Update(int l, int r, int pre, int c, int v){
int now = ++tot;
cnt[now] = cnt[pre] + v;
if(l < r){
int m = l+r >> ;
if(c <= m){
rson[now] = rson[pre];
lson[now] = Update(l, m, lson[pre], c, v);
}
else {
lson[now] = lson[pre];
rson[now] = Update(m+, r, rson[pre], c, v);
}
}
return now;
} void dfs(int o, int u){
deep[u] = deep[o] + ;
root[u] = Update(, t, root[o], id(w[u]), );
for(int i = ; i < son[u].size(); i++){
int v = son[u][i];
if(v == o) continue;
anc[v][] = u;
for(int j = ; j < ; j++) anc[v][j] = anc[anc[v][j-]][j-];
dfs(u, v);
}
}
int lca(int u, int v){
if(deep[u] < deep[v]) swap(u, v);
for(int i = ; i >= ; i--)
if(deep[anc[u][i]] >= deep[v]) u = anc[u][i];
if(u == v) return v;
for(int i = ; i >= ; i--)
if(anc[u][i] != anc[v][i])
u = anc[u][i], v = anc[v][i];
return anc[u][];
}
int Query(int l, int r, int c1, int c2, int d1, int d2, int k){
if(l == r) return a[l];
int m = l+r >> ;
int num = cnt[lson[c1]] + cnt[lson[c2]] - cnt[lson[d1]] - cnt[lson[d2]];
if(num >= k) return Query(l, m, lson[c1], lson[c2], lson[d1], lson[d2], k);
else return Query(m+, r, rson[c1], rson[c2], rson[d1], rson[d2], k-num);
}
int main(){
int n, q, u, v, k, p, z;
scanf("%d%d", &n, &q);
for(int i = ; i <= n; i++){
scanf("%d", &w[i]);
a[i] = w[i];
}
for(int i = ; i < n; i++){
scanf("%d%d", &u, &v);
son[u].pb(v);
son[v].pb(u);
}
sort(a+, a++n);
for(int i = ; i <= n; i++) a[++t] = a[i];
root[] = Build(, t);
dfs(, );
while(q--){
scanf("%d%d%d", &u, &v, &k);
z = lca(u, v);
p = anc[z][];
printf("%d\n", Query(, t, root[u], root[v], root[z], root[p], k));
}
return ;
}

Count on a tree

Count on a tree 树上区间第K小的更多相关文章

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

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

  2. SPOJ-COT-Count on a tree(树上路径第K小,可持久化线段树)

    题意: 求树上A,B两点路径上第K小的数 分析: 同样是可持久化线段树,只是这一次我们用它来维护树上的信息. 我们之前已经知道,可持久化线段树实际上是维护的一个前缀和,而前缀和不一定要出现在一个线性表 ...

  3. E - Count on a tree 树上第K小

    主席树的入门题目,这道题的题意其实就是说,给你一棵树,询问在两个节点之间的路径上的区间第K小 我们如何把树上问题转换为区间问题呢? 其实DFS就可以,我们按照DFS的顺序,对线段树进行建树,那么这个树 ...

  4. Count on a tree 树上主席树

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

  5. 线段树维护区间前k小

    线段树维护区间前k小 $ solution: $ 觉得超级钢琴太麻烦?在这里线段树提供一条龙服务 . 咳咳,开始讲正题!这道题我们有一个和超级钢琴复杂度一样 $ ~O(~\sum x\times lo ...

  6. 主席树总结(经典区间第k小问题)(主席树,线段树)

    接着上一篇总结--可持久化线段树来整理吧.点击进入 这两种数据结构确实有异曲同工之妙.结构是很相似的,但维护的主要内容并不相同,主席树的离散化.前缀和等思想也要更难理解一些. 闲话 话说刚学习主席树的 ...

  7. A - 低阶入门膜法 - K-th Number (主席树查询区间第k小)

    题目链接:https://cn.vjudge.net/contest/284294#problem/A 题目大意:主席树查询区间第k小. 具体思路:主席树入门. AC代码: #include<i ...

  8. HDU 2665.Kth number 区间第K小

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. POJ 2014.K-th Number 区间第k小 (归并树)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 57543   Accepted: 19893 Ca ...

随机推荐

  1. java并发笔记之四synchronized 锁的膨胀过程(锁的升级过程)深入剖析

    警告⚠️:本文耗时很长,先做好心理准备,建议PC端浏览器浏览效果更佳. 本篇我们讲通过大量实例代码及hotspot源码分析偏向锁(批量重偏向.批量撤销).轻量级锁.重量级锁及锁的膨胀过程(也就是锁的升 ...

  2. 阿里云Linxu下的Mysql安装与配置

    说明:本文主要详细介绍了关于如何在阿里云ECS服务器上安装并配置Mysql 环境:Centos 7版本,阿里云部署好系统后会默认安装mariadb数据库 1.删除阿里云自带的MariaDB # rpm ...

  3. x32下PsSetLoadImageNotifyRoutine的逆向

    一丶简介 纯属兴趣爱好.特来逆向玩玩. PsSetLoadImageNotifyRoutine 是内核中用来监控模块加载.操作系统给我们提供的回调. 我们只需要填写对应的回调函数原型即可进行加监控. ...

  4. jdk8与jdk7中hashMap的resize分析

    在分析代码之前,我们先抛出下面的问题: hashmap 扩容时每个 entry 需要再计算一次 hash 吗? 我们首先看看jdk7中的hashmap的resize实现 1 void resize(i ...

  5. 夯实Java基础(六)——包装类

    1.包装类简介 我们都知道Java是面向对象编程语言,包含了8种基本数据类型,但是这8种基本数据类型并不支持面向对象的特征,它们既不是类,也不能调用方法.这在实际使用时存在很多的不便,比如int类型需 ...

  6. form提交的几种方式

    背景 一直使用postman作为restful接口的调试工具,但是针对post方法的几种类型,始终不明白其含义,今天彻底了解了下 form提交的来源 html页面上的form表单 <form a ...

  7. [转载]使用Java操作Mongodb

    HelloWorld程序 学习任何程序的第一步,都是编写HelloWorld程序,我们也不例外,看下如何通过Java编写一个HelloWorld的程序. 首先,要通过Java操作Mongodb,必须先 ...

  8. Spring 集成Kafka(完整版)

    前面的文章我们已经完成了Kafka基于Zookeeper的集群的搭建了.Kafka集群搭建请点我.记过几天的研究已经实现Spring的集成了.本文重点 jar包准备 集成是基于spring-integ ...

  9. AUTOCAD二次开发-----删除一个图层里面的所有对象

    https://blog.csdn.net/aasswwe/article/details/40899759 private void Test() { // 获取当前文档和数据库 Document ...

  10. Netbeans courier new 乱码问题

    Netbeans 默认的字体 monospaced,显示英文的单引号及字体非常的不好看,在网上查了下资料可以变得很好看. 1.仍然保持默认字体 monospaced 2.在Netbeans 的安装目  ...