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. Mac 常用属性

    如果需要让隐藏的文件可见. 具体做法就是打开一个Terminal终端窗口,输入以下命令: 对于OS X Mavericks 10.9: defaults write com.apple.finder ...

  2. python 基础 7.7 json--上

                                                                                              一. 文件json ...

  3. python 基础 6.1 异常处理方法

      一. Excepthion 异常类    Excepthion 是所有的异常基础类(),对于python 的标准异常,我们列出如下,以做参考:   异常名称                     ...

  4. COGS410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  5. 使用python实现二分法查找

    最近开始学习mit的python课程,其中手工实现的一个关于二分法查找的练习代码个人感觉比较有参考价值,贴上来分享交流一下. 主要功能是在1-100中自己猜测一个数值,随后系统产生数值看是否符合猜测, ...

  6. ABap-小技巧

    if FIELD cn '0123456789'. *&如果字符串包含‘数字’    STOP.  endif. 同理到字母‘ABCDEFG*’ 'abcdefg*' '/' '\' 等其它字 ...

  7. 【Linux】服务器之间的免密登录脚本

    在实际运维的过程中,经常需要用到免密登录,下面这个脚本实现服务器之间的免密登录,如下 比如,要实现A服务器与B.C.D服务器的免密登录,只需要将B.C.D服务器的IP地址写在serverlist.tx ...

  8. BZOJ 1041 [HAOI2008]圆上的整点:数学【费马平方和定理】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1041 题意: 给定n(n <= 2*10^9),问你在圆x^2 + y^2 = n^ ...

  9. BZOJ 1572 [Usaco2009 Open]工作安排Job:贪心 + 优先队列【先放再更新】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1572 题意: 有n个工作,每个工作有一个截止日期dead[i]和收益pay[i]. 完成一 ...

  10. java 基础 - 反转字符串

    反转字符串 public class Main { public static void main(String[] args) { String newStr= strReverseWithArra ...