http://www.spoj.com/problems/COT/ 树上第k小元素

LCA + 可持久化线段树

每个新的版本都是由其父亲版本转化而来。

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring> using namespace std; const int maxn = 1e5 + ;
const int maxd = ;
struct Edge{
int v, next;
}p[maxn << ];
int head[maxn], e, d[maxn], f[maxn][maxd];
//LCA
void init(){
memset(d, , sizeof(d));
memset(f, , sizeof(f));
memset(head, -, sizeof(head));
e = ;
}
void addEdge(int u, int v){
p[e].v = v; p[e].next = head[u]; head[u] = e++;
swap(u, v);
p[e].v = v; p[e].next = head[u]; head[u] = e++;
}
int lca(int u, int v){
if (d[u] < d[v]) swap(u, v);
int k = d[u] - d[v];
for (int i = ; i < maxd; ++i)
if (( << i) & k) u = f[u][i];
if (u == v) return u;
for (int i = maxd - ; i >= ; --i){
if (f[u][i] != f[v][i]){
u = f[u][i];
v = f[v][i];
}
}
return f[u][];
}
//CMT
int ls[maxn * ], rs[maxn * ], sum[maxn * ], T[maxn], tot, rt;
int num[maxn], san[maxn], n, m; // 离散化前点数,离散化后点数
void init_hash(){
for (int i = ; i <= n; ++i) san[i] = num[i];
sort(san + , san + n + );
m = unique(san + , san + n + ) - san - ;
}
int hash(int x){
return lower_bound(san + , san + m + , x) - san;
}
void build(int l, int r, int& rt){
rt = ++ tot; sum[rt] = ;
if (l == r) return;
int mid = (l + r) >> ;
build(l, mid, ls[rt]);
build(mid + , r, rs[rt]);
}
void update(int last, int pos, int l, int r, int& rt){
rt = ++ tot;
ls[rt] = ls[last], rs[rt] = rs[last], sum[rt] = sum[last] + ;
if (l == r) return ;
int mid = (l + r) >> ;
if (pos <= mid) update(ls[last], pos, l, mid, ls[rt]);
else update(rs[last], pos, mid + , r, rs[rt]);
}
int query(int pos, int left_rt, int right_rt, int lca_rt, int l, int r, int k){
if (l == r) return l;
int mid = (l + r) >> ;
int cnt = sum[ls[left_rt]] + sum[ls[right_rt]] - * sum[ls[lca_rt]] + (pos >= l && pos <= mid);//注意lca为跟的时候
if (k <= cnt) return query(pos, ls[left_rt], ls[right_rt], ls[lca_rt], l, mid, k);
else return query(pos, rs[left_rt], rs[right_rt], rs[lca_rt], mid + , r, k - cnt);
}
//LCA && CMT
void dfs(int u, int fa){
f[u][] = fa;//注意
d[u] = d[f[u][]] + ;
update(T[fa], hash(num[u]), , m, T[u]);
for (int i = ; i < maxd; ++i) f[u][i] = f[ f[u][i - ] ][i - ];
for (int i = head[u]; ~i; i = p[i].next){
if (p[i].v == fa) continue;
dfs(p[i].v, u);
}
}
int main(){
int q, u, v, k;
while (scanf("%d%d", &n, &q) == ){
for (int i = ; i <= n; ++i) scanf("%d", &num[i]);
init();
init_hash();
tot = ;
for (int i = ; i < n; ++i){
scanf("%d%d", &u, &v);
addEdge(u, v);
}
build(, m, T[]);
dfs(, );
while (q--){
scanf("%d%d%d", &u, &v, &k);
printf("%d\n",san[query(hash(num[lca(u, v)]), T[u], T[v], T[lca(u, v)],, m, k)]);
}
}
return ;
}

最新文章

  1. 运行带cocoa pods 的项目,遇到的问题是找不到文件,解决办法
  2. C#中XmlTextWriter读写xml文件详细介绍(转)
  3. jqgrid在colModel中多次调用同一个字段值
  4. winform插件机制学习
  5. [转]CABasicAnimation用法
  6. #Linux学习笔记# 自定义shell终端提示符
  7. 三层架构与MVC的PK--ASP.NET MVC图解(一)
  8. dubbo + zookeeper 环境搭建
  9. HTML5另类塔防游戏 -《三国战线》公布
  10. java中jsoup框架解析html
  11. Spring Task Scheduler - No qualifying bean of type [org.springframework.scheduling.TaskScheduler] is defined
  12. Git的简单安装
  13. Ubuntu热键控制spotify播放和音量调节
  14. 哈密顿绕行世界问题(dfs+记录路径)
  15. c语言中宏定义和常量定义的区别
  16. SQLServer之事务简介
  17. Eclipse与github整合
  18. .NET Core HttpClient调用腾讯云对象存储Web API的&quot;ERROR_CGI_PARAM_NO_SUCH_OP&quot;问题
  19. vue中watch的详细用法
  20. python3学习笔记之安装

热门文章

  1. Yasm 1.3.0 Release Notes
  2. spring 动态定时任务
  3. Memory Barriers
  4. Jquery DataTables 自定义布局sdom
  5. Unity AssetBundle 踩坑记录
  6. MyTools
  7. ibatis--百度百科
  8. Cocos2dx 3.6源代码编译错误:syntax error : missing &amp;#39;)&amp;#39; before &amp;#39;{&amp;#39;
  9. 我也来谈谈使用Zen Coding快速开发html和css原理
  10. chrome mp4格式支持问题