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. [Spring boot] Configuring and Accessing a Data Source

    We need our data persistence with configuring our datasouce: In application.properties: spring.h2.co ...

  2. 【转】Python——编码规范

    来自于 啄木鸟社区 Python Coding Rule --- hoxide 初译 dreamingk 校对发布 040724 --- xyb 重新排版 040915 --- ZoomQuiet M ...

  3. ant-design 实现 添加页面

    1.逻辑代码 /** * 添加用户 */ import React,{PureComponent} from 'react' import {Card,Form,Input,Select,Button ...

  4. win10 rabbitMQ的安装与测试

    安装 1.首先,下载并运行Erlang for Windows 安装程序 (地址:http://www.erlang.org/downloads)下载完毕并安装(注意:安装目录请选择默认目录) 2.下 ...

  5. 第四天 ThinkPHP手把手高速拼接站点(四)

    6月6日,晴天."熟梅天气豆生蛾.一见榴花感慨多. 芒种积阴凝雨润,菖蒲修剪莫蹉跎. " 九.后台编写-续-1 1.改动admin/Tpl/Login/index.html 自己改 ...

  6. CentOS 7中mariadb编译安装教程systemctl启动

    mariadb做为mysql的替代品 现在centos的新版本yum包已换成mariadb 跟上篇一样只是启动方式改为systemd 安装一些库 yum install gcc gcc-c++ wge ...

  7. Linux Tools

    WinSCP  http://winscp.net/eng/download.php Xshell 5

  8. atitit.TokenService  token服务模块的设计

    atitit.TokenService  token服务模块的设计 1. Token的归类1 2. Token的用途2 2.1. 访问控制2 2.2. 编译原理术语)编辑2 2.3. 数据处理2 1. ...

  9. iOS9编程GOGOGO:XCode7新变化

    做一个关于栈视图 UIStackView的Demo,先看看XCode7的变化 关于StoryBoard: 启动画面由xib变为Storyboard StoryBoard引用: 如今能够在一个Story ...

  10. PLSQL Developer 9注册码

    Product Code:46jw8l8ymfmp2twwbuur8j9gv978m2q2duserial Number:307254password:xs374ca