HDU4366 Successor

Successor

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



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
 

Author
FZU
 

Source
2012 Multi-University Training Contest 7

题意:一家公司公司有n-1个员工和一个老板,老板的编号是0,员工是1-n,每个员工都有忠诚度和能力值,现在老板想辞去一个人,现在就需要从这个员工的下属里这出一个人来顶替他,顶替的员工要满足能力值不小于辞去的员工,有多个员工满足要求,输出这些员工里忠诚度最大的员工的编号,没有满足输出-1。
分析:输入的是一棵树,先把这棵树上的每个点变成区间上的某个点,这样,父树的区间范围肯定包含子树的区间范围,然后按能力值从大到小排序,然后再依次插入这些点,如果有人可以剃这个员工能力值一定比这个员工大或等于,也就是说在这之前就插入了,而且只能由低一级的替换高一级的,所以要替换高一级的,高一级的那段区间肯定包含低一级的那段,所以可以查询到,线段树里维护一个最大的忠诚度。(在sort那里多打了个+1,RE了好久)。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
const int MAX=100110;
struct seg
{
    int l,r;
    int mx;
}tree[MAX*2];
struct Node
{
    int loy;
    int abt;
    int id;
}p[MAX];
map<int,int> map1;
vector<int> g[MAX];
int ans[MAX],n,m;
bool cmp(Node x,Node y)
{
    return x.abt>y.abt;
}
int l[MAX],r[MAX];
int num;
void dfs(int k)
{
    l[k]=num++;
    for(int i=0;i<g[k].size();i++)
        dfs(g[k][i]);
    r[k]=num;
}
void build(int l,int r,int k)
{
    tree[k].l=l;
    tree[k].r=r;
    tree[k].mx=-1;
    if(l==r)
        return;
    int mid=(l+r)>>1;
    build(l,mid,2*k);
    build(mid+1,r,2*k+1);
}
void insert(int n,int d,int k)
{
    if(tree[k].l==tree[k].r&&tree[k].l==n)
    {
        tree[k].mx=d;
        return;
    }
    int mid=(tree[k].l+tree[k].r)>>1;
    if(n<=mid)
        insert(n,d,2*k);
    else
        insert(n,d,2*k+1);
    tree[k].mx=max(tree[2*k].mx,tree[2*k+1].mx);
}
int query(int l,int r,int k)
{
    if(r<l)
        return -1;
    if(tree[k].l==l&&tree[k].r==r)
        return tree[k].mx;
    int mid=(tree[k].l+tree[k].r)>>1;
    if(r<=mid)
        return query(l,r,2*k);
    else if(l>mid)
        return query(l,r,2*k+1);
    else
        return max(query(l,mid,2*k),query(mid+1,r,2*k+1));
}
void init()
{
    for(int i=0;i<=n;i++)
        g[i].clear();
    map1.clear();
    num=0;
}
int main()
{
    int t,loy,abt,i,j,x,u;
    //freopen("in.txt","r",stdin);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        init();
        for(i=1;i<n;i++)
        {
            scanf("%d%d%d",&u,&loy,&abt);
            g[u].push_back(i);
            p[i].abt=abt;
            p[i].loy=loy;
            p[i].id=i;
            map1[loy]=i;
        }
        dfs(0);
        build(0,num-1,1);
        sort(p+1,p+n,cmp);
        for(i=1;i<n;i=j)
        {
            j=i;
            while(j<n&&p[i].abt==p[j].abt)
            {
                int id=p[j].id;
                loy=query(l[id]+1,r[id]-1,1);
                if(loy!=-1)
                    ans[id]=map1[loy];
                else
                    ans[id]=-1;
                j++;
            }
            j=i;
            while(j<n&&p[i].abt==p[j].abt)
            {
                int id=p[j].id;
                insert(l[id],p[j].loy,1);
                j++;
            }
        }
        while(m--)
        {
            scanf("%d",&x);
            printf("%d\n",ans[x]);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值