SPOJ Count on a tree(主席树+LCA)
一、题目
COT - Count on a tree
You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer weight.
We will ask you to perform the following operation:
- u v k : ask for the kth minimum weight on the path from node u to node v
Input
In the first line there are two integers N and M. (N, M <= 100000)
In the second line there are N integers. The ith integer denotes the weight of the ith node.
In the next N-1 lines, each line contains two integers u v, which describes an edge (u, v).
In the next M lines, each line contains three integers u v k, which means an operation asking for the kth minimum weight on the path from node u to node v.
Output
For each operation, print its result.
Example
Input: 8 5 105 2 9 3 8 5 7 7 1 2 1 3 1 4 3 5 3 6 3 7 4 82 5 12 5 22 5 32 5 47 8 2
Output: 2891057 题目链接:http://www.spoj.com/problems/COT/二、思路 原理其实和一维线性表序列的一样。只不过这是在树上操作。 在一维线性表序列中,扫描序列中每一个离散化后的数字,每一次新建的权值线段树都是基于前一次的。而在树中,对每一个子节点的数字,新建的线段树都是基于父节点的线段树的。
***************************未完待续……
***************************
三、源代码
#pragma GCC optimize(2) #pragma comment(linker, "/STACK:102400000, 102400000") #include<bits/stdc++.h> using namespace std; typedef long long LL; #define MAXN 111111 LL n, q, m; /*************树部分*******************/ typedef struct { int to, next; } Edge; Edge tree[MAXN * ]; int head[MAXN], ecnt; void add(int from, int to) { tree[ecnt].to = to; tree[ecnt].next = head[from]; head[from] = ecnt++; } /*************树部分*******************/ /*************LCA部分*******************/ ], depth[MAXN]; void dfs4lca(int r, int par, int d) { parent[r][] = par, depth[r] = d; ; i = tree[i].next) { int to = tree[i].to; if(to != par) dfs4lca(to, r, d + ); } } void init4lca() { dfs4lca(, -, ); ; k < ; ++k) { ; v <= n; ++v) { ) parent[v][k + ] = -; else parent[v][k + ] = parent[parent[v][k]][k]; } } } int lca(int a, int b) { if(depth[a] < depth[b]) swap(a, b); ; i < ; ++i) { ) a = parent[a][i]; } if(a == b) return a; ; i >= ; --i) { if(parent[a][i] != parent[b][i]) { a = parent[a][i]; b = parent[b][i]; } } ]; } /*************LCA部分*******************/ /*************主席树部分*******************/ struct { int lch, rch, cnt; } nodes[MAXN * ]; int root[MAXN], ncnt; , int r = m) { if(!nroot) { nroot = ++ncnt; nodes[nroot].cnt = nodes[proot].cnt + ; } if(l == r) return; ; if(val <= mid) { nodes[nroot].rch = nodes[proot].rch; update(nodes[nroot].lch, nodes[proot].lch, val, l, mid); } else { nodes[nroot].lch = nodes[proot].lch; update(nodes[nroot].rch, nodes[proot].rch, val, mid + , r); } } , int r = m) { if(l == r) return l; int cnt = nodes[nodes[uroot].lch].cnt + nodes[nodes[vroot].lch].cnt - nodes[nodes[lcaroot].lch].cnt - nodes[nodes[lcafroot].lch].cnt; ; if(k <= cnt) return query(nodes[uroot].lch, nodes[vroot].lch, nodes[lcaroot].lch, nodes[lcafroot].lch, k, l, mid); else , r); } /*************主席树部分*******************/ /*************离散化部分*******************/ LL weight[MAXN], buf[MAXN], mp[MAXN]; int nwt[MAXN]; void discrete() { memcpy(buf + , weight + , ]) * n); sort(buf + , buf + n + ); m = unique(buf + , buf + n + ) - buf - ; ; i <= n; ++i) { nwt[i] = lower_bound(buf + , buf + m + , weight[i]) - buf; mp[nwt[i]] = weight[i]; } } /*************离散化部分*******************/ template <class T> inline void read(T &x) { int t; bool flag = false; ')) ; if(t == '-') flag = true, t = getchar(); x = t - '; ') x = x * + t - '; if(flag) x = -x; } void init() { memset(head, -, sizeof(head)); ecnt = ; //nodes = 0, root = 0, ncnt = 0; } void dfs4tree(int r, int par) { ; i = tree[i].next) { int to = tree[i].to; if(to != par) { update(root[to], root[r], nwt[to]); dfs4tree(to, r); } } } int main() { #ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); #endif // ONLINE_JUDGE init(); LL a, b, u, v, k, wt, uvlca, ans; scanf("%lld%lld", &n, &q); ; i <= n; ++i) { read(weight[i]); } ; i < n; ++i) { read(a), read(b); add(a, b); add(b, a); } init4lca(); discrete(); add(, );//添加一条虚边。 dfs4tree(, -); while(q--) { read(u), read(v), read(k); uvlca = LL(lca(u, v)); ans = mp[query(root[u], root[v], root[uvlca], root[parent[uvlca][]], int(k))]; printf("%lld\n", ans); } ; }
SPOJ Count on a tree(主席树+LCA)的更多相关文章
- 【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
分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...
- spoj COT - Count on a tree(主席树 +lca,树上第K大)
您将获得一个包含N个节点的树.树节点的编号从1到Ñ.每个节点都有一个整数权重. 我们会要求您执行以下操作: uvk:询问从节点u到节点v的路径上的第k个最小权重 输入 在第一行中有两个整数Ñ和中号.( ...
- [bzoj2588][count on a tree] (主席树+lca)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- 洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...
- 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 ...
- spoj cot: Count on a tree 主席树
10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 3749 Solved: 873[ ...
- 洛谷P2633 Count on a tree(主席树上树)
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
随机推荐
- Composite(组合)
意图: 将对象组合成树形结构以表示“部分-整体”的层次结构.C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性. 适用性: 你想表示对象的部分-整体层次结构. 你希望用户 ...
- redis的过期策略以及内存淘汰机制
redis采用的是定期删除+惰性删除策略. 为什么不用定时删除策略? 定时删除,用一个定时器来负责监视key,过期则自动删除.虽然内存及时释放,但是十分消耗CPU资源.在大并发请求下,CPU要将时间应 ...
- css可应用的渐进增强新特性
1. 让有滚动行为的元素平滑滚动 scroll-behavior: smooth; <div class="smooth"> </dvi> .smooth ...
- vue项目打包部署到nginx 服务器上
假如要实现的效果如下 http://ip/vue =>是进入首页访问的路径是 usr/local/nginx/html/vue http://ip/website =>是进 ...
- C# 使用Dictionary、linq实现根据集合里面的字符串进行分组
//对下面集合里面的字符串按照“_”进行分组. List<string> list = new List<string>() { "1_32", " ...
- sqlserver存储过程分页
create procedure [dbo].[SqlPager]@sqlstr nvarchar(4000), --查询字符串@currentpage int, --第N页@pagesize in ...
- Android之Glide(非常好用的图片加载框架)
谷歌开发者论坛上,谷歌为我们介绍了一个名叫 Glide 的图片加载库,作者是bumptech. Glide是一种快速.高效的开源媒体管理和Android的包裹mediadecoding图像加载框架,内 ...
- Arrays.copyof(···)与System.arraycopy(···)区别
首先观察先System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)的声明: public stati ...
- windows 下搭建python虚拟环境
###################################windows 下测试环境 C:\Users\wongg\django-cmdb>cd ..\cmdb ##下载get-pi ...
- 043——VUE中组件之使用.sync修饰符与computed计算属性实现购物车原理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...