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 ;
}

spoj 10628的更多相关文章

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

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

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

  4. Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...

  5. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  6. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

  7. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

  8. 2588: Spoj 10628. Count on a tree

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5766  Solved: 1374 ...

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

  10. bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)

    Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 7669  Solved: 1894[Submi ...

随机推荐

  1. 转:JavaWeb学习总结(一) 写得相当不错

    这个系列写的相当不错,浅显易懂,图文并茂 http://www.cnblogs.com/xdp-gacl/tag/JavaWeb%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93 ...

  2. c# word 操作

    public class WordOperate { #region 新建Word文档 /// <summary> /// 动态生成Word文档并填充内容 /// </summary ...

  3. [TypeScript] Dynamically initialize class properties using TypeScript decorators

    Decorators are a powerful feature of TypeScript that allow for efficient and readable abstractions w ...

  4. 两列布局(浮动、定位、flex)和三列布局(圣杯、双飞翼、flex)

    demo 各种布局演示 https://jsfiddle.net/mayufo/qp890peq/1/ 两栏布局 浮动 <div class="box1"> <d ...

  5. 倍福TwinCAT(贝福Beckhoff)应用教程12.2 TwinCAT控制松下伺服 NC初步

    在前面我们已经学会了使用贝福自带的调试软件完成试运行,接下来是使用TWINCAT PLC实现这个功能,右击PLC添加一个PLC项目   在VISUs上右击添加一个HMI人机界面   目前PLC程序和人 ...

  6. js bind 绑定this指向

    1.示例代码 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UT ...

  7. Redis 3.2.8 集群模式+Sentinel多Master部署

    环境准备CentOS 7.3redis1 172.18.1.101:7001 masterredis2 172.18.1.102:7002 masterredis3 172.18.1.103:7003 ...

  8. C语言-一个fopen函数中未使用二进制模式(b)引发的血案

    转自:http://blog.csdn.net/hinyunsin/article/details/6401854 最近写了一个网络文件传输模块,为了让这个模块具有更好的移植性,我尽量使用C标准IO ...

  9. Xilinx-7Series-FPGA高速收发器使用学习—概述与参考时钟篇

    xilinx的7系列FPGA根据不同的器件类型,集成了GTP.GTX.GTH以及GTZ四种串行高速收发器,四种收发器主要区别是支持的线速率不同,图一可以说明在7系列里面器件类型和支持的收发器类型以及最 ...

  10. varnish学习笔记

    varnish cache是一款开源的高性能的缓存server.和老牌的Squid对照有例如以下长处. 1:varnish是基于内存缓存数据的,所以处理速度比Squid要快. 2:varnish支持更 ...