spoj 10628
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的更多相关文章
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- 2017.11.15 String、StringBuffer、StringBuilder的比较(todo)
参考来自:http://blog.csdn.net/jeffleo/article/details/52194433 1.速度 一般来说,三者的速度是:StringBuilder > Strin ...
- C#文本之XML
格式化XML public static string FormatXML(string XMLstring) { //校验是否是XML报文 if (!XMLstring.Contains(" ...
- poj_1284_原根
一開始看题的时候第一想法就是暴力,可是无奈数据量有点大,看了题解之后才知道原来牵扯到数论上的一个叫做原根的东西,这个题的题意就是,给你一个奇素数,问题他的原根有多少.依据初等数论上所说,此时牵扯到了三 ...
- 两个IP实现IIS和Apache公用80端口的设置方法
1. 打开命令提示符并确保您位于 X:\Inetpub\Adminscripts 文件夹(其中 X 是 IIS 安装驱动器)中.为此,请在命令提示符下键入以下命令行: X: CD \Inetpub ...
- [Typescript] Make TypeScript Class Usage Safer with Strict Property Initialization
By setting the strictPropertyInitialization flag in the .tsconfig file, TypeScript will start throwi ...
- utf8和utf-8的区别?
utf8和utf-8的区别? utf-8和utf8的区别? 今天再次区别 相信很多程序员刚开始也会有这样的疑惑,如题,我也是. 其实,他们可以这样来区分. 一.在php和html中设置编码,请 ...
- Commons-VFS 使用SFTP
http://pro.ctlok.com/2011/06/apache-commons-vfs-for-sftp.html
- ajax请求web容器控制超时
1.项目用到超时控制,针对ajax请求超时,可以参照如下解决方案 tomcat容器 web.xml 中配置 <session-config> <session-timeout> ...
- 二维数组,锯齿数组和集合 C# 一维数组、二维数组(矩形数组)、交错数组(锯齿数组)的使用 C# 数组、多维数组(矩形数组)、锯齿数组(交叉数组)
二维数组,锯齿数组和集合 一.二维数组 二维数组:一维数组----豆角二维数组----表格 定义:1.一维数组:数据类型[] 数组变量名 = new 数据类型[数组长度];数据类型[] 数组变量名 = ...
- 使用NPOI读取Excel出错
使用NPOI读取Excel出错,错误信息:java.io.IOException: Invalid header signature; read 4503608217567241, expected ...