cogs2790. mk和tree解题报告
【题目描述】
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解题报告相关推荐
- 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)
[LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...
- 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 ...
- LeetCode 1104. Path In Zigzag Labelled Binary Tree解题报告
1104. Path In Zigzag Labelled Binary Tree Path In Zigzag Labelled Binary Tree python solution 题目描述 I ...
- 【LeetCode】538. Convert BST to Greater Tree 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...
- 655. Print Binary Tree 解题报告(树)
第一部分:搜索.遍历 [例子1]655. Print Binary Tree Example 1: Input:1/2 Output: [["", "1", & ...
- 【原创】leetCodeOj ---Convert Sorted List to Binary Search Tree 解题报告
原题地址: https://oj.leetcode.com/problems/convert-sorted-list-to-binary-search-tree/ 题目内容: Given a sing ...
- 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 ...
- 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 ...
- Sicily 1156. Binary tree 解题报告
题目地址:1156. Binary tree 思路: 简单的一道二叉树相关的题目,题目会给出一颗树现在的形态,然后用前序遍历这棵树的节点输出数据即可. 每个节点会输入该节点的identifier,有点 ...
- [poj1741]tree 解题报告
经典的点分做法就不说了(然而我写点分t了..) 线段树/平衡树启发式合并的话,就是维护子树每个节点到子树跟的距离,打一个整棵子树的标记,然后按dfs/bfs序启发式合并,合并之前先查询一下答案即可. ...
最新文章
- Android开发--事件的处理/按键按下,弹起,触摸事件等
- tensorflow dataset_ops shuffle()方法 (随机重新排列此数据集的元素)
- tensorflow实现手写数字识别(MNIST)
- Django缓存和内置信号
- 集群服务负载均衡------LVS
- virtualbox中windows虚拟机安装增强功能
- Interrupted Exception异常可能没你想的那么简单!
- ssm实现管理员和用户_基于SSM的网上水果生鲜超市商城管理系统
- Citrix,微软,VMware:它们的优缺点(资料整理汇集)
- 加深认识与理解ADO.NET
- 【Android基础】android shape详解
- Sun JVM 内存管理、参数与调优、内存分配与回收策略、GC 日志配置使用详解
- summit超级计算机gpu温度,揭秘Summit:加速计算赋力全球最快超级计算机
- Mac 修改 hosts 文件
- ChainX 主网预演暨第三届创世节点大赛正式启动
- CSS文字排版终极指南
- Linux查看ip 地址命令(ip addr)
- 【问题解决】Linux服务器免密信任 远程执行
- linux 查看kernel log,Linux Kernel Log
- Excel的文件打开特别慢,xls文件特别大解决一例