题意:每个人都有一个上司,每个人都有能力值和忠诚值,0是老板,现在给出m个询问,每次询问给出一个x,要求你找到x的所有直系和非直系下属中能力比他高的最忠诚的人是谁

思路:因为树上查询很麻烦,所以我们直接dfs序把关系变成线性。然后我们再分块,把每个块按照能力值升序排列,这样我们就能直接二分查找这个块内能力值大于x的数就是二分出来的数到块末尾的所有数。但是怎么查找最忠诚的?我们直接预处理每个块内i位置到块末尾的最忠诚人的位置就行了。

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
struct node{
int name, loyalty, ability;
bool operator < (const node &x) const{
return ability < x.ability;
}
}p[maxn];
int loyalty[maxn], ability[maxn];
int in[maxn], out[maxn]; //在dfs序列中的位置1-id
int belong[maxn], id;
int head[maxn], tot;
struct Edge{
int to, next;
}edge[maxn];
void init(){
tot = id = ;
memset(head, -, sizeof(head));
}
void addEdge(int u, int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs(int u){
in[u] = ++id;
p[id].ability = ability[u], p[id].loyalty = loyalty[u], p[id].name = u;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to;
dfs(v);
}
out[u] = id;
}
int MaxLoy[maxn]; //从位置j到所属块末尾的最大loyalty的人在dfs序列的位置
int n, m, block, sz;
int solve(int x){
int l = belong[in[x]], r = belong[out[x]];
int L, R;
int MaxLoyalty = -, ans = -; L = block * (l - ) + , R = min(L + block - , id);
for(int i = L; i <= R; i++){
if(in[p[i].name] > in[x] && out[p[i].name] <= out[x]){
if(p[i].loyalty > MaxLoyalty && p[i].ability > ability[x]){
MaxLoyalty = p[i].loyalty;
ans = p[i].name;
}
}
}
L = l + , R = r - ;
node c;
c.ability = ability[x];
for(int i = L; i <= R; i++){
int s = block * (i - ) + , e = s + block;
int pos = upper_bound(p + s, p + e, c) - p;
if(pos >= e) continue;
int tmp = MaxLoy[pos];
if(p[tmp].loyalty > MaxLoyalty){
MaxLoyalty = p[tmp].loyalty;
ans = p[tmp].name;
}
}
L = block * (r - ) + , R = min(L + block - , id);
for(int i = L; i <= R; i++){
if(in[p[i].name] > in[x] && out[p[i].name] <= out[x]){
if(p[i].loyalty > MaxLoyalty && p[i].ability > ability[x]){
MaxLoyalty = p[i].loyalty;
ans = p[i].name;
}
}
}
return ans;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
init();
int a;
scanf("%d%d", &n, &m);
ability[] = -, loyalty[] = -;
for(int i = ; i <= n - ; i++){
scanf("%d%d%d", &a, &loyalty[i], &ability[i]);
addEdge(a, i);
}
dfs();
block = (int)sqrt(id * 1.0);
for(int i = ; i <= id; i++){
belong[i] = (i - ) / block + ;
}
sz = belong[id];
for(int i = ; i <= sz; i++){
int s = block * (i - ) + , e = min(s + block, id + );
sort(p + s, p + e);
int Max = -, pos;
for(int j = e - ; j >= s; j--){
if(Max < p[j].loyalty){
Max = p[j].loyalty;
pos = j;
}
MaxLoy[j] = pos;
}
}
while(m--){
scanf("%d", &a);
printf("%d\n", solve(a));
}
}
return ;
}

HDU 4366 Successor(dfs序 + 分块)题解的更多相关文章

  1. HDU - 4366 Successor DFS序 + 分块暴力 or 线段树维护

    给定一颗树,每个节点都有忠诚和能力两个参数,随意指定一个节点,要求在它的子树中找一个节点代替它,这个节点要满足能力值大于它,而且是忠诚度最高的那个. 首先,dfs一下,处理出L[i], R[i]表示d ...

  2. HDU 4366 Successor( DFS序+ 线段树 )

    Successor Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  3. HDU - 4366 Successor DFS区间+线段树

    Successor:http://acm.hdu.edu.cn/showproblem.php?pid=4366 参考:https://blog.csdn.net/colin_27/article/d ...

  4. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  5. hdu 4366 Successor - CDQ分治 - 线段树 - 树分块

    Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty an ...

  6. HDU 4366 Successor 分块做法

    http://acm.hdu.edu.cn/showproblem.php?pid=4366 今日重新做了这题的分块,果然是隔太久了,都忘记了.. 首先,用DFS序变成一维的问题 关键是它有两个权值, ...

  7. HDU4366 Successor【dfs序 分块】

    HDU4366 Successor 题意: 给出一棵根为\(1\)的树,每个点有两个权值\(x,y\),每次询问一个点的子树中\(x\)比这个点的\(x\)大且\(y\)值最大的那个点 题解: 如果以 ...

  8. 【HDU4366】【DFS序+分块】Successor

    Problem Description Sean owns a company and he is the BOSS.The other Staff has one Superior.every st ...

  9. HDU 3974 Assign the task(DFS序)题解

    题意:给出一棵树,改变树的一个节点的值,那么该节点及所有子节点都变为这个值.给出m个询问. 思路:DFS序,将树改为线性结构,用线段树维护.start[ ]记录每个节点的编号,End[ ]为该节点的最 ...

随机推荐

  1. Vue系列之 => 组件切换

    组件切换方式一 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  2. html5-特殊符号的使用

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  3. 支持向量机SVM 参数选择

    http://ju.outofmemory.cn/entry/119152 http://www.cnblogs.com/zhizhan/p/4412343.html 支持向量机SVM是从线性可分情况 ...

  4. codeforces 979C Kuro and Walking Route

    题意: 给出一棵树,其中有两个点,x和y,限制走了x之后的路径上不能有y,问可以走的路径(u,v)有多少条,(u,v)和(v,u)考虑为两条不同的路径. 思路: 简单树形dp,dfs统计在x到y路径( ...

  5. 【转】SQLyog SSH 密钥登陆认证提示: No supported authentication methods available 解决方法

    问题背景: 问题原因: SQLyog不支持非标准的的私钥格式 解决方案: 使用puttyGen重新导入原来的私钥,然后重新保存成PPK证书文件,最后用SQLyog加载该PPK文件即可. 效果截图: 原 ...

  6. 普通程序员转型AI免费教程整合,零基础也可自学

    普通程序员转型AI免费教程整合,零基础也可自学 本文告诉通过什么样的顺序进行学习以及在哪儿可以找到他们.可以通过自学的方式掌握机器学习科学家的基础技能,并在论文.工作甚至日常生活中快速应用. 可以先看 ...

  7. system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk

    elasticsearch启动时遇到的错误 这个是elasticsearch配置文件的问题. 解决办法: 在elasticsearch.yml配置文件中 添加     bootstrap.system ...

  8. httpclient get post

    https://www.cnblogs.com/wutongin/p/7778996.html post请求方法和get请求方法 package com.xkeshi.paymentweb.contr ...

  9. JXNU暑期选拔赛

    最小的数 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submissi ...

  10. xml.dom——文档对象模型API

    文档对象模型,或者“DOM”,是一个跨语言API的World Wide Web Consortium(W3C)来访问和修改XML文档.DOM的实现提供了一个XML文档树结构,或允许客户机代码从头开始建 ...