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. iclass 鎖機鎖程序破解限制方法-適合于有用google login 的App

    此法適合于有用google login 的App,只需要去到 app login 界面, 找到 “log in with google” , 然後向下滾動,找到最下面的 “説明” ,點擊進去,就會見到 ...

  2. ARB扩展与标准OpenGL的关系

    由于OpenGL的标准更新不是很频繁,因此,当某种技术应用流行起来时,显卡厂商为了支持该技术,会使用自己的扩展来实现该功能.但是不同厂商如果有不同的实现,那么程序编写将会异常繁琐.因此多个厂商共同协商 ...

  3. UUID相同导致的网络连接问题

    目录 场景 思路 解决过程 提升虚拟机配置 直连交换机 最终解决方案 总结 场景 有同事从公司寄了一台服务器到现场,用来安装数据库.缓存等组件供开发使用.到了之后,连接电源.网线,设置IP,用vSph ...

  4. 【VS开发】【Live555-rtsp】在windows 使用vs2008编译live555

    在windows 使用vs2008编译live555 基于 liveMedia的程序,需要通过继承UsageEnvironment抽象类和TaskScheduler抽象类,定义相应的类来处理事件调度, ...

  5. JavaScript日期格式化处理

    /** * 获取年月,如:2018-08 */ export function getMonth () { return formatDate(new Date(), 'yyyy-MM') } /** ...

  6. sublime的Package Control的安装及使用

    一.快速安装 使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令行,粘贴如下代码(注意下面代码为一行): import urllib.request,os; pf = ...

  7. 使用nfsstat命令查看NFS服务器状态

    转载于:http://www.cnblogs.com/jankie/archive/2011/09/03/2165851.html nfsstat命令显示关于NFS和到内核的远程过程调用(RPC)接口 ...

  8. 第十三章 字符串(一)之 String

    这一节来学习String的特性和方法. 一.String对象的不变性 不变性:String对象是由一个final char[] value 数组实现的,因此String对象是不可变的.任何看起来改变S ...

  9. 使用Minikube运行一个本地单节点Kubernetes集群(阿里云)

    使用Minikube运行一个本地单节点Kubernetes集群中使用谷歌官方镜像由于某些原因导致镜像拉取失败以及很多人并没有代理无法开展相关实验. 因此本文使用阿里云提供的修改版Minikube创建一 ...

  10. YAPTCHA(HDU2973)【威尔逊定理】

    威尔逊原理.即对于素数p,有(p-1)!=-1( mod p). 首先,将原式变形为[ (3×k+6)! % (3×k+7) + 1] / (3×k+7),所以: 1.3×k+7是素数,结果为1, 2 ...