Successor

HDU - 4366

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序)的更多相关文章

  1. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  2. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  3. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  4. 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序

    题目大意 ​ Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...

  5. 【bzoj4817】树点涂色 LCT+线段树+dfs序

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  6. HDU 5692 线段树+dfs序

    Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  7. R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数

    R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...

  8. hdu 5039 线段树+dfs序

    http://acm.hdu.edu.cn/showproblem.php?pid=5039 给定一棵树,边权为0/1.m个操作支持翻转一条边的权值或者询问树上有多少条路径的边权和为奇数. 用树形df ...

  9. 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

    3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] ...

  10. 【BZOJ-3306】树 线段树 + DFS序

    3306: 树 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 792  Solved: 262[Submit][Status][Discuss] De ...

随机推荐

  1. 【miscellaneous】单播、广播和多播IP地址

    转自:http://www.cnblogs.com/gaoxing/archive/2012/02/19/2358484.html 除地址类别外,还可根据传输的消息特征将IP地址分为单播.广播或多播. ...

  2. CSS - Animate动画

    下载地址:https://daneden.github.io/animate.css/ 关键CSS样式:animate.css 引入CSS样式 <link rel="styleshee ...

  3. httpContext.User.Identity.IsAuthenticated 总是为fasle

    验证一直通不过,不知道问题在哪里.这个坑应该只有我自己遇到,记录一下,问题在使用swagger验证的时候出现的(说的很轻松) 如图所示,在swaager文档中,添加认证功能,此时只要我们填下登陆时获取 ...

  4. PHP中各种强大的函数

    获取时间   data(https://www.cnblogs.com/mrluotong/p/5895375.html):strtotime() <?php echo "今天:&qu ...

  5. Vuex的简单认识

    一. 什么是vuex? Vuex是一个专为了vue.js 应用程序开发的状态管理模式 二.为什么要用vuex? 构建一个大型单页面应用程序时,Vuex可以更好的帮我们的组件外部更好的统一管理状态 类似 ...

  6. linux用户和组 只 组的管理

    1. groupadd 新建组, 组名最长不能超过32个字节 groupadd -create a new group 语法: groupadd [option] 组名 -g, --gid GID   ...

  7. Linux系列:之软件安装

    1.安装软件 不同的Linux版本可能使用不同的软件管理机制. RPM:使用这类命令进行安装的Linux版本有CentOS. DPKG:使用这类命令进行安装的Linux版本有Debian.Ubuntu ...

  8. python 2 和 python 3的区别

    python2和python3区别 ​ python2:源码不统一,源码(功能)重复,维护困难,除法的时候返回来的是小数点,()浮点数 ​ python3:源码统一,源码不重复,除法的时候返回来的是整 ...

  9. Elastic Search常用元数据简介

    在ES中,除了定义的index,type,和管理的document外,还有若干的元数据.这些元数据用于记录ES中需要使用的核心数据.在ES中,元数据通常使用下划线’_’开头. 1 查看数据GET /i ...

  10. MySQL之主键

    一.主键  primary key (唯一标识 .不能重复.不能为空) 1.主键-----是表中的字段,这个字段能唯一标识一条记录.例如 学生表(学号.姓名,年级)里的学号,不能重复.不能为空: 课程 ...