Successor

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2559    Accepted Submission(s): 613

Problem Description
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.
 
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.
 
Sample Input
1
3 2
0 100 99
1 101 100
1
2
 
Sample Output
2
-1
 
 
题意: 给一棵树,每个结点有两个值a和b,再有m个查询,查询问一个点的编号u,要求找出u的后代中某个结点v,v.a值比u.a大,v.b是所有后代中最大的那个点编号
 
思路: 先按照员工关系构出一棵树, 然后将树的dfs深度序列转化为线性序列,按这个序列确定各员工在线段树中的位置。将员工按ability从大到小排序,然后逐个插入线段树相应位置,每次插入前查询以其为根的子树区间中loyalty的最大值及其对应员工。处理完上面之后,对于询问O(1)输出。
 
代码:
C++交会RE,然后要手动加栈,时间200+ms
G++不需要手动加栈就过了,时间300+ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
const int N = ; struct _edge{
int to,next;
};
_edge edge[N*];
int ecnt,head[N];
void addedge(int u,int v)
{
edge[ecnt].to = v;
edge[ecnt].next = head[u];
head[u] = ecnt++;
}
struct node{
int id,a,b,l,r;
friend bool operator < (const node &a, const node &b)
{
return a.a>b.a;
}
}; int n,m,M;
int zkw[N*][];
node man[N];
int ans[N];
int dfscnt;
void dfs(int u,int fa)
{
man[u].l = dfscnt++;
for(int e=head[u];e!=-;e=edge[e].next)
{
int &v = edge[e].to;
if(v==fa) continue;
dfs(v,u);
}
man[u].r = dfscnt++;
} void add(int x,int a,int b)
{
for(x+=M;x;x>>=)
if(zkw[x][]<a)
zkw[x][]=a,zkw[x][]=b;
}
int query(int l,int r)
{
int a,b;
a=b=-;
for(l=l+M-,r=r+M+;l^r^;l>>=,r>>=)
{
if(~l& && zkw[l^][]>a) a=zkw[l^][],b=zkw[l^][];
if(r& && zkw[r^][]>a) a=zkw[r^][],b=zkw[r^][];
}
return b;
} void run()
{
scanf("%d%d",&n,&m);
memset(head,-,sizeof(head));
ecnt=;
int a,b,c;
for(int i=;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
addedge(a,i);
addedge(i,a);
man[i].a=c;
man[i].b=b;
man[i].id=i;
}
dfscnt=;
dfs(,-);
// for(int i=0;i<n;i++)
// printf("%d %d %d\n",i,man[i].l,man[i].r);
sort(man+,man+n); for(M=;M<=dfscnt+;M*=);
memset(zkw,-,sizeof(zkw)); stack<int> stk;
stk.push();
ans[man[].id]=-;
for(int i=;i<n;i++)
{
if(man[i].a!=man[i-].a)
{
while(!stk.empty())
{
int u = stk.top(); stk.pop();
add(man[u].l,man[u].b,man[u].id);
add(man[u].r,man[u].b,man[u].id);
}
}
stk.push(i);
ans[man[i].id] = query(man[i].l,man[i].r);
}
while(m--)
{
scanf("%d",&a);
printf("%d\n",ans[a]);
}
} int main()
{
freopen("case.txt","r",stdin);
int _;
scanf("%d",&_);
while(_--)
run();
return ;
}

hdu4366 Successor (dfs序+zkw线段树)的更多相关文章

  1. bzoj3306: 树(dfs序+倍增+线段树)

    比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...

  2. bzoj2819 DFS序 + LCA + 线段树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2819 题意:树上单点修改及区间异或和查询. 思维难度不高,但是题比较硬核. 整体思路是维护每一个结 ...

  3. Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)

    877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...

  4. 用dfs序处理线段树的好题吗?

    https://www.cnblogs.com/mountaink/p/9878918.html 分析:每次的选取必须选最优的一条链,那我们考虑一下选择这条链后,把这条路上的点的权值更新掉,再采取选最 ...

  5. 7月13日考试 题解(DFS序+期望+线段树优化建图)

    T1 sign 题目大意:给出一棵 N 个节点的树,求所有起点为叶节点的有向路径,其 上每一条边权值和的和.N<=10000 水题.考试的时候毒瘤出题人(学长orz)把读入顺序改了一下,于是很多 ...

  6. hdu 3974 Assign the task(dfs序上线段树)

    Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...

  7. Luogu P2982 [USACO10FEB]慢下来 Slowing down | dfs序、线段树

    题目链接 题目大意: 有一棵N个结点树和N头奶牛,一开始所有奶牛都在一号结点,奶牛们将按从编号1到编号N的顺序依次前往自己的目的地,求每头奶牛在去往自己目的地的途中将会经过多少已经有奶牛的结点. 题解 ...

  8. Codeforces Round #200 (Div. 1) D. Water Tree(dfs序加线段树)

    思路: dfs序其实是很水的东西.  和树链剖分一样, 都是对树链的hash. 该题做法是:每次对子树全部赋值为1,对一个点赋值为0,查询子树最小值. 该题需要注意的是:当我们对一棵子树全都赋值为1的 ...

  9. URAL 1890 . Money out of Thin Air (dfs序hash + 线段树)

    题目链接: URAL 1890 . Money out of Thin Air 题目描述: 给出一个公司里面上司和下级的附属关系,还有每一个人的工资,然后有两种询问: 1:employee x y z ...

随机推荐

  1. 远程访问(post 传参数) 以及IOUtils复制文件

    package com.action; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream ...

  2. Activity设置style透明后与SurfaceView合用引发的无形命案

    近期搞视频通话,SurfaceView是不可缺少的,因为启动视频要载入一些资源,比較耗时.会有1.2s黑屏的现象,为了改善用户体验,我们须要设置Activity的Theme为透明风格(QQ 也是如此) ...

  3. LeetCode:矩形区域【223】

    LeetCode:矩形区域[223] 题目描述 在二维平面上计算出两个由直线构成的矩形重叠后形成的总面积. 每个矩形由其左下顶点和右上顶点坐标表示,如图所示. 示例: 输入: -3, 0, 3, 4, ...

  4. Flask简介

    一. Python 现阶段三大主流Web框架 Django Tornado Flask 对比 1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不 ...

  5. DOM的介绍

    一 . DOM 介绍 什么是DOM DOM:文档对象模型.DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构.目的其实就是为了能让js操作html元素而制定的一个规范. DOM就是由节 ...

  6. spring-boot5

    Spring Boot集成MyBatis: (1)新建maven project;取名为:spring-boot-mybatis (2)在pom.xml文件中引入相关依赖: (3)创建启动类App.j ...

  7. TensorFlow Action(开山使用篇)

    1.TensorFlow安装: 使用pip install tensorflow安装CPU版: 或使用pip install tensorflow-gpu==1.2.1指定版本安装GPU版. 2.Te ...

  8. 只会用就out了,手写一个符合规范的Promise

    Promise是什么 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Prom ...

  9. Window7 环境下 MariaDB 的安装 及使用

    MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可.开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区采用分支的方 ...

  10. <算法笔记>关于快速排序的算法优化排序(顺便给百度百科纠个错)

    快速排序是排序算法之中的基本中的基本,虽然越来越多的接口函数将快速排序“完美的封装了起来”,比如C++中的qsort或者<algorithm>中的sort(与stable_sort相对应) ...