Successor HDU - 4366 (预处理,线段树,dfs序)
Successor
Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty and ability.Some times Sean will fire one staff.Then one of the fired man’s Subordinates will replace him whose ability is higher than him and has the highest loyalty for company.Sean want to know who will replace the fired man.
公司里的每个员工都有一个忠诚度和能力值。如果把一个员工开除,需要在他的下属中,找到一个能力值比他高,且忠诚度最大的员工来替代他。
Input
In the first line a number T indicate the number of test cases. Then for each case the first line contain 2 numbers n,m (2<=n,m<=50000),indicate the company has n person include Sean ,m is the times of Sean’s query.Staffs are numbered from 1 to n-1,Sean’s number is 0.Follow n-1 lines,the i-th(1<=i<=n-1) line contains 3 integers a,b,c(0<=a<=n-1,0<=b,c<=1000000),indicate the i-th staff’s superior Serial number,i-th staff’s loyalty and ability.Every staff ‘s Serial number is bigger than his superior,Each staff has different loyalty.then follows m lines of queries.Each line only a number indicate the Serial number of whom should be fired.
第一行一个整数,表示测试数据组数。
对于每组数据,第一行两个整数n和m,表示公司的员工和询问次数。
接下来n-1行,第i行,3个整数,i的上级,忠诚度,能力值。老总的编号为0,所有员工的忠诚度都不一样。
接下来m行,每行一个整数,表示要开除某个人,你需要输出替代他的员工编号。如果不存在,输出-1.
Output
For every query print a number:the Serial number of whom would replace the losing job man,If there has no one to replace him,print -1.
对于每个要开除的人,你需要输出替代他的员工编号。如果不存在,输出-1.
Sample Input
1
3 2
0 100 99
1 101 100
1
2
Sample Output
2
-1
题意:
公司里自上而下是一个树形结构。
每个员工都有一个忠诚度和能力值。如果把一个员工开除,需要在他的下属中,找到一个能力值比他高,且忠诚度最大的员工来替代他。
m个询问,每行一个整数,表示要开除某个人,你需要输出替代他的员工编号。如果不存在,输出-1.
思路:
一棵树的子树中,dfs序是连续的。
所以我们先通过dfs来把树形问题转为区间问题。
又因为所有员工的忠诚度都不一样。 所以我们可以用一个map把员工的编号和忠诚度对应起来。
我们先以员工的能力值为指标,降序排序。
然后预处理出所有答案,输入直接O(1) 输出结果。
如何预处理出所有员工节点的答案呢?
我们知道推论①:一个员工对他的领导的答案值有影响,当且仅当这个员工的能力值大于他的那个领导的答案值。
那么我们可以在排序后,
在线段树中从大到小依次加入员工,
这样的话我们对一个员工,询问线段树中这个员工的dfs序的时间戳区间中的忠诚度的最大值。(区间查询)
中横渡对应下编号就是这个员工的答案。
然后把这位员工的忠诚度加入到员工的dfs序的时间戳位置中。(单点更新)
为什么这样对?
因为对上面讲到的推论①,对其可能有影响的员工已经全部加入到线段树中了。
他只需要询问在自己的下属员工中(在时间戳区间中)的忠诚度最大值即可。
细节见代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
// #define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 50010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int T;
map<int, int> mp;
std::vector<int> son[maxn];
int tree[maxn << 2];
int ans[maxn];
int n, m;
int tot;
void init()
{
repd(i, 1, n * 4) {
tree[i] = -1;
}
tot = 0;
mp.clear();
repd(i, 0, n) {
son[i].clear();
ans[i] = -1;
}
mp[-1] = -1;
}
struct node {
int ab;
int lo;
int id;
int timel;
int timer;
bool operator <(const node &bb )const
{
if (ab != bb.ab) {
return ab > bb.ab;
} else {
return timel < bb.timel;
}
}
} data[maxn];
void dfs(int x)
{
data[x].timel = ++tot;
for (auto y : son[x]) {
dfs(y);
}
data[x].timer = tot;
}
int ask(int rt, int l, int r, int ql, int qr)
{
if (ql <= l && r <= qr) {
return tree[rt];
}
int res = -1;
int mid = (l + r) >> 1;
if (ql <= mid) {
res = max(res, ask(rt << 1, l, mid, ql, qr));
}
if (qr > mid) {
res = max(res, ask(rt << 1 | 1, mid + 1, r, ql, qr));
}
return res;
}
void update(int rt, int l, int r, int pos, int val)
{
if (l == r && l == pos) {
tree[rt] = val;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) {
update(rt << 1, l, mid, pos, val);
}
if (pos > mid) {
update(rt << 1 | 1, mid + 1, r, pos, val);
}
tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]);
}
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
scanf("%d", &T);
while (T--) {
scanf("%d %d", &n, &m);
init();
int x;
repd(i, 1, n - 1) {
scanf("%d %d %d", &x, &data[i].lo, &data[i].ab);
data[i].id = i;
mp[data[i].lo] = i;
son[x].push_back(i);
}
dfs(0);
sort(data + 1, data + n);
for (int i = 1; i < n; ++i) {
ans[data[i].id] = mp[ask(1, 1, tot, data[i].timel, data[i].timer)];
update(1, 1, tot, data[i].timel, data[i].lo);
}
while (m--) {
int x;
scanf("%d", &x);
printf("%d\n", ans[x] );
}
}
return 0;
}
inline void getInt(int *p)
{
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
} else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
Successor HDU - 4366 (预处理,线段树,dfs序)的更多相关文章
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序
题目大意 Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- HDU 5692 线段树+dfs序
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数
R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...
- hdu 5039 线段树+dfs序
http://acm.hdu.edu.cn/showproblem.php?pid=5039 给定一棵树,边权为0/1.m个操作支持翻转一条边的权值或者询问树上有多少条路径的边权和为奇数. 用树形df ...
- 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序
3779: 重组病毒 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 224 Solved: 95[Submit][Status][Discuss] ...
- 【BZOJ-3306】树 线段树 + DFS序
3306: 树 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 792 Solved: 262[Submit][Status][Discuss] De ...
随机推荐
- 20190925 - macOS 的包管理工具
众所周知,macOS 的包管理工具有 MacPorts 和 Homebrew,后者似乎更受欢迎,但前者但包数量更多. 喜欢手冲咖啡,看到 brew 这个词有好感,但可能部分由于网络的问题,部分因为 b ...
- spring-cloud-starter-stream-rocketmq 坑点j记录
- 实例一 airflow_failover
源码: https://github.com/teamclairvoyant/airflow-scheduler-failover-controller #怎么判断scheduler是running的 ...
- Anaconda Spyder 常用快捷键
Ctrl+1 注释.取消注释 Ctrl+4/5 块注释 / 取消块注释 Ctrl+D 删除一行 Ctrl+L 转到行 Ctrl+G/左键 查找函数定义 F9 运行选中代码 F12 断点 / 取消断点 ...
- dev控件学习笔记之----CxGrid
本人总结的DEV学习:希望对大家有所帮助. 一.是否显示分组工具: 二.表格左边记录信息显示的宽度: 三.设置表格行高: 四.表头文件的水平和垂直设置:多个设置用按住SHIFT后进行多选,然后就可以设 ...
- 处理idea加载不到Spring的xml或者properties配置文件
在pom文件的 标签钱添加以下代码 <!--防止ieda加载不到xml或者properties文件开始--> <resources> <resource> < ...
- Django-choices字段值对应关系(性别)-MTV与MVC科普-Ajax发json格式与文件格式数据-contentType格式-Ajax搭配sweetalert实现删除确认弹窗-自定义分页器-批量插入-07
目录 models 字段补充 choices 参数/字段(用的很多) MTV与MVC模型 科普 Ajax 发送 GET.POST 请求的几种常见方式 用 Ajax 做一个小案例 准备工作 动手用 Aj ...
- linux内核钩子--khook
简介 本文介绍github上的一个项目khook,一个可以在内核中增加钩子函数的框架,支持x86.项目地址在这里:https://github.com/milabs/khook 本文先简单介绍钩子函数 ...
- Linux(CentOS)下安装NVIDIA GPU驱动
GCC 官网:http://gcc.gnu.org 1)检查 NVIDIA驱动需要GCC等C/C++开发环境,首先检测GCC是否已经安装 gcc –v# 如果系统显示没有找到GCC指令,或没有显示GC ...
- java进程CPU高分析
JVM导致系统CPU高的常见场景: 内存不足,JVM gc频繁,一般会伴随OOMJVM某个线程死循环或者递归调用 定位和解决1.内存不足,gc频繁可参考我的这遍文章解决.https://blog.cs ...