【题目描述】

mk有一棵树,每个节点有一个权值 现在他想知道 u->v的树上路径中 第k大的数是多少

【输入格式】

第一行一个整数n(1<=n<=100000) 树的节点个数

第2-n行每行2个整数x,y (1<=x,y<=n)意思是x与y之间连边

第n+1行 n个整数 第i个整数vi表示第i个节点的权值

第n+2行 1个整数m(1<=m<=100000) 表示询问数

接下来m行 每行3个整数 a,b,c

意思是询问a到b的树上路径上第k大节点的权值

【输出格式】

m行 每行一个整数x 表示询问的结果

【样例输入】

6

1 2

2 3

2 4

4 5

4 6

5 7 8 6 4 3

3

3 5 2

2 5 1

5 6 3

【样例输出】

6

4

6

数据范围

30%1<=n,m<=100

50%1<=n,m<=5000

100%1<=n,m<=100000,0<=vi<=10^9,1<=x,y<=n,k

保证输入必定合法

【来源】

ryz hnsdfz集训《数据结构》例题cot

题解:

对每个节点建立从根到该节点的主席树 那么单次查询变成了u+v-lca(u,v)-fa[lca(u,v) 查询第k大与1维第k大相同

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=100000+10;
vector<int>A[maxn];
int v[maxn];
int B[maxn];
int hash[maxn];
int root[maxn*100],ls[maxn*100],rs[maxn*100];
int sum[maxn*100];
int top[maxn],dep[maxn],fa[maxn],size[maxn],son[maxn];
int tot=0;
int sz=0;
inline int bs(int x){int l=1,r=tot;while(l+1<r){int mid=(l+r)>>1;if(hash[mid]>=x)r=mid;else l=mid+1;}if(hash[l]==x)return l;else return r;
}
inline void insert(int &rt,int y,int l,int r,int x){rt=++sz;sum[rt]=sum[y]+1;ls[rt]=ls[y];rs[rt]=rs[y];if(l==r)return ;int mid=(l+r)>>1;if(mid>=x)insert(ls[rt],ls[y],l,mid,x);else insert(rs[rt],rs[y],mid+1,r,x);
}
inline int query(int u,int v,int lca,int fl,int l,int r,int k){if(l==r)return l;int mid=(l+r)>>1;int tmp=sum[ls[u]]+sum[ls[v]]-sum[ls[fl]]-sum[ls[lca]];if(tmp>=k)return query(ls[u],ls[v],ls[lca],ls[fl],l,mid,k);else return query(rs[u],rs[v],rs[lca],rs[fl],mid+1,r,k-tmp);
}
inline void dfs1(int x,int f,int d){dep[x]=d;fa[x]=f;int u=bs(v[x]);insert(root[x],root[f],1,tot,u);size[x]=1;for(int i=0;i<A[x].size();i++){u=A[x][i];if(u==f)continue;dfs1(u,x,d+1);size[x]+=size[u];if((size[u]>size[son[x]]&&son[x])||!son[x])son[x]=u;}
}
inline void dfs2(int x,int tp){top[x]=tp;if(!son[x])return ;dfs2(son[x],tp);for(int i=0;i<A[x].size();i++){int u=A[x][i];if(u==son[x]||u==fa[x])continue;dfs2(u,u);}
}
inline int Lca(int x,int y){while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);x=fa[top[x]];}if(dep[x]>dep[y])swap(x,y);return x;
}
int main(){freopen("mktree.in","r",stdin);freopen("mktree.out","w",stdout);int n;   scanf("%d",&n);int x,y;for(int i=1;i<n;i++){scanf("%d %d",&x,&y);A[x].push_back(y);A[y].push_back(x);}for(int i=1;i<=n;i++){scanf("%d",&v[i]);B[i]=v[i];}sort(B+1,B+n+1);hash[++tot]=B[1];for(int i=2;i<=n;i++)if(B[i]!=B[i-1])hash[++tot]=B[i];dfs1(1,0,1);dfs2(1,1);int m;scanf("%d",&m);int z;for(int i=1;i<=m;i++){scanf("%d %d %d",&x,&y,&z);int lc=Lca(x,y);printf("%d\n",hash[query(root[x],root[y],root[lc],root[fa[lc]],1,tot,z)]);}
return 0;
}

]

cogs2790. mk和tree解题报告相关推荐

  1. 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)

    [LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...

  2. POJ 2054 Color a Tree解题报告

    题干 Bob is very interested in the data structure of a tree. A tree is a directed graph in which a spe ...

  3. LeetCode 1104. Path In Zigzag Labelled Binary Tree解题报告

    1104. Path In Zigzag Labelled Binary Tree Path In Zigzag Labelled Binary Tree python solution 题目描述 I ...

  4. 【LeetCode】538. Convert BST to Greater Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...

  5. 655. Print Binary Tree 解题报告(树)

    第一部分:搜索.遍历 [例子1]655. Print Binary Tree Example 1: Input:1/2 Output: [["", "1", & ...

  6. 【原创】leetCodeOj ---Convert Sorted List to Binary Search Tree 解题报告

    原题地址: https://oj.leetcode.com/problems/convert-sorted-list-to-binary-search-tree/ 题目内容: Given a sing ...

  7. LeetCode: Convert Sorted Array to Binary Search Tree 解题报告

    Convert Sorted Array to Binary Search Tree Given an array where elements are sorted in ascending ord ...

  8. LeetCode Convert Sorted List to Binary Search Tree 解题报告

    Given a singly linked list where elements are sorted in ascending order, convert it to a height bala ...

  9. Sicily 1156. Binary tree 解题报告

    题目地址:1156. Binary tree 思路: 简单的一道二叉树相关的题目,题目会给出一颗树现在的形态,然后用前序遍历这棵树的节点输出数据即可. 每个节点会输入该节点的identifier,有点 ...

  10. [poj1741]tree 解题报告

    经典的点分做法就不说了(然而我写点分t了..) 线段树/平衡树启发式合并的话,就是维护子树每个节点到子树跟的距离,打一个整棵子树的标记,然后按dfs/bfs序启发式合并,合并之前先查询一下答案即可. ...

最新文章

  1. Android开发--事件的处理/按键按下,弹起,触摸事件等
  2. tensorflow dataset_ops shuffle()方法 (随机重新排列此数据集的元素)
  3. tensorflow实现手写数字识别(MNIST)
  4. Django缓存和内置信号
  5. 集群服务负载均衡------LVS
  6. virtualbox中windows虚拟机安装增强功能
  7. Interrupted Exception异常可能没你想的那么简单!
  8. ssm实现管理员和用户_基于SSM的网上水果生鲜超市商城管理系统
  9. Citrix,微软,VMware:它们的优缺点(资料整理汇集)
  10. 加深认识与理解ADO.NET
  11. 【Android基础】android shape详解
  12. Sun JVM 内存管理、参数与调优、内存分配与回收策略、GC 日志配置使用详解
  13. summit超级计算机gpu温度,揭秘Summit:加速计算赋力全球最快超级计算机
  14. Mac 修改 hosts 文件
  15. ChainX 主网预演暨第三届创世节点大赛正式启动
  16. CSS文字排版终极指南
  17. Linux查看ip 地址命令(ip addr)
  18. 【问题解决】Linux服务器免密信任 远程执行
  19. linux 查看kernel log,Linux Kernel Log
  20. Excel的文件打开特别慢,xls文件特别大解决一例

热门文章

  1. 分享一个空手反套白狼的骚操作
  2. 服务器运行cad慢,CAD绘图如何提高效率!CAD运行用加速技巧图文教程
  3. 如何将ppt压缩到最小?
  4. 如何调整gif动图的速度?1分钟在线调节gif动图速度
  5. oracle 批量修改同义词,Oracle批量创建同义词
  6. 19清明假前一周安排
  7. 豆瓣排名前500的电视剧
  8. 清除Mac电脑缓存的方法,非常实用哦
  9. (解读)什么是渗透测试(Penetration Testing)?
  10. 逆流而上,整合阿里高频考点2023Java岗面试突击指南手册最新首发