Count on a tree(SPOJ COT + 树上第k大 + 主席树 + LCA)
题目链接:https://www.spoj.com/problems/COT/en/
题目:

题意:
给你一棵有n个节点的树,求节点u到节点v这条链上的第k大。
思路:
我们首先用dfs进行建题目给的树,然后在dfs时进行主席树的update操作。众所周知,主席树采用的是前缀和思想,区间第k大是与前一个树添加新的线段树,而树上第k大则是与父亲节点添加新的线段树,因而在此思想上此题的答案为sum[u] + sum[v] - sum[lca(u,v)] - sum[fa[lca(u,v)]。求第k大操作和区间第k大一样,就不描述了~
代码实现如下:
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pli;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n");
#define debug(x) cout<<#x"=["<<x<<"]" <<endl;
#define FIN freopen("/home/dillonh/CLionProjects//in.txt", "r", stdin);
#define FOUT freopen("D://code//out.txt", "w", stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0); const double eps = 1e-;
const int mod = ;
const int maxn = + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, q, tot, cnt, x, y, k, len;
int head[maxn], root[maxn];
int a[maxn], deep[maxn], fa[maxn][];
vector<int> v; struct edge {
int v, next;
}ed[maxn<<]; void addedge(int u, int v) {
ed[tot].v = v;
ed[tot].next = head[u];
head[u] = tot++;
ed[tot].v = u;
ed[tot].next = head[v];
head[v] = tot++;
} struct node {
int l, r, sum;
}tree[maxn*]; int getid(int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin() + ;
} void update(int l, int r, int& x, int y, int pos) {
tree[++cnt] = tree[y], tree[cnt].sum++, x = cnt;
if(l == r) return;
int mid = (l + r) >> ;
if(mid >= pos) update(l, mid, tree[x].l, tree[y].l, pos);
else update(mid + , r, tree[x].r, tree[y].r, pos);
} int query(int l, int r, int x, int y, int p, int pp, int k) {
if(l == r) return l;
int mid = (l + r) >> ;
int sum = tree[tree[x].l].sum + tree[tree[y].l].sum - tree[tree[p].l].sum - tree[tree[pp].l].sum;
if(sum >= k) return query(l, mid, tree[x].l, tree[y].l, tree[p].l, tree[pp].l, k);
else return query(mid + , r, tree[x].r, tree[y].r, tree[p].r, tree[pp].r, k - sum);
} void dfs(int u, int d, int p) {
deep[u] = d;
fa[u][] = p;
update(, len, root[u], root[p], getid(a[u]));
for(int i = head[u]; ~i; i = ed[i].next) {
int v = ed[i].v;
if(v != p) {
dfs(v, d + , u);
}
}
} void lca() {
for(int i = ; i <= n; i++) {
for(int j = ; ( << j) <= n; j++) {
fa[i][j] = -;
}
}
for(int j = ; ( << j) <= n; j++) {
for(int i = ; i <= n; i++) {
if(fa[i][j-] != -) {
fa[i][j] = fa[fa[i][j-]][j-];
}
}
}
} int cal(int u, int v) {
if(deep[u] < deep[v]) swap(u, v);
int k;
for(k = ; ( << ( + k)) <= deep[u]; k++);
for(int i = k; i >= ; i--) {
if(deep[u] - ( << i) >= deep[v]) {
u = fa[u][i];
}
}
if(u == v) return u;
for(int i = k; i >= ; i--) {
if(fa[u][i] != - && fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][];
} int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
scanf("%d%d", &n, &q);
memset(head, -, sizeof(head));
for(int i = ; i <= n; i++) scanf("%d", &a[i]), v.push_back(a[i]);
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
len = v.size();
for(int i = ; i < n; i++) scanf("%d%d", &x, &y), addedge(x, y);
dfs(, , );
lca();
while(q--) {
scanf("%d%d%d", &x, &y, &k);
int p = cal(x, y);
printf("%d\n", v[query(, len, root[x], root[y], root[p], root[fa[p][]], k)-]);
}
return ;
}
Count on a tree(SPOJ COT + 树上第k大 + 主席树 + LCA)的更多相关文章
- 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)
Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...
- 🔺Count on a tree SPOJ - COT (无能为力。。。)
https://cn.vjudge.net/problem/SPOJ-COT 插上 大佬的代码 和 我的...以后再看吧... Count on a tree 大佬:http://www.cnblog ...
- Count on a tree SPOJ - COT (主席树,LCA)
You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer ...
- 【SPOJ】Count On A Tree II(树上莫队)
[SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...
- Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)
Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...
- HDU 4729 An Easy Problem for Elfness (主席树,树上第K大)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意:给出一个带边权的图.对于每一个询问(S , ...
- 树上第k大联通块
题意:求树上第k大联通块 n,k<=1e5 考虑转化为k短路的形式. 也就是要建出一张图是的这条图上每一条S到T的路径都能代表一个联通块. 点分治建图 递归下去,假定每个子树的所有联通块中都可以 ...
- SPOJ 10628 COT - Count on a tree(在树上建立主席树)(LCA)
COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...
- SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解
题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...
随机推荐
- 结对项目——fault,error,failure的程序设计
一.结对编程内容: 1.不能触发Fault. 2.触发Fault,但是不触发Error. 3.触发Error,但不触发Failure. 二.结对编程人员 1.周宗耀.周浩: 2.结对截图: 三.结对项 ...
- get_list_by_where
/** * 查询数据 * @param $param * @param bool $get_rows 或者总数 * @param bool $get_one 或者一条记录 * @param bool ...
- perf的采样模式和统计模式
perf的采样模式和统计模式 统计模式和采样模式使用寄存器的方法不相同; 在统计模式下,每次调度之前设置寄存器,调度之后清理寄存器,留个下个进程使用;PMU寄存器的使用方法; 在采样模式下,每次 pm ...
- Java知识点整理(三)
如何设计出高可用的分布式架构 分布式架构 CDN简介 分布式缓存和本地缓存区别 高并发场景常用技术解决方案 JVM优化示例 Docker和JVM区别 Java开发人员需要注意的五大Docker误区 D ...
- 【前端学习笔记04】JavaScript数据通信Ajax方法封装
//Ajax 方法封装 //设置数据格式 function setData(data){ if(!data){ return ''; } else{ var arr = []; for(k in da ...
- 【笔记】sublime 一些常用功能和快捷键
Ctrl+D 选词 (反复按快捷键,即可继续向下同时选中下一个相同的文本进行同时编辑)Ctrl+G 跳转到相应的行Ctrl+J 合并行(已选择需要合并的多行时)Ctrl+L 选择整行(按住-继续选择下 ...
- BZOJ 2424 订货(贪心+单调队列)
怎么题解都是用费用流做的啊...用单调队列多优美啊. 题意:某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初 ...
- [codeforces696B]Puzzles
B. Puzzles time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...
- 使DIV相对窗口大小左右拖动始终水平居中
<!doctype html> <html> <head> <meta http-equiv="content-type" content ...
- Kerberos的黄金票据详解
0x01黄金票据的原理和条件 黄金票据是伪造票据授予票据(TGT),也被称为认证票据.如下图所示,与域控制器没有AS-REQ或AS-REP(步骤1和2)通信.由于黄金票据是伪造的TGT,它作为TGS- ...