HDU 4366

来源:互联网 发布:mac系统删除应用程序 编辑:程序博客网 时间:2024/06/18 14:09

线段树    

题意: 每个员工有一个上级,每个上级有很多下级,求fire掉一个人之后可以用哪个人顶上


/*线段树    题意: 每个员工有一个上级,每个上级有很多下级,求fire掉一个人之后可以用哪个人顶上替换规则:该员工的能力比他高的下级中, loyalty最大的那个,如果没有,则输出 -1思路:员工的上下级关系应该是一棵树,dfs,dfs次序对应转化为一维之后的下标{[()]},就像这样;      一棵子树的结点对应成线段上的点总是连续的,我们记录开始结点ll,跟结束结点rr;          那么求该子树根节点用哪个替换就转化成求[ll,rr]区间上,ability比根节点大的中loyalty最大的;            将结点按ability按从大到小排序,然后一个个依次加入线段树中,这样就能保证在当前结点加入前,线段树      中结点的ability都是比它大的,先求该节点的[ll,rr]区间内loyalty最大的,然后加入该节点      线段树要维护的就是最大的loyalty,又因loyalty是唯一的,所以可以对应员工编号*/#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<cstdlib>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define N 50005#include<map>using namespace std;int Max[N<<2],ans[N],head[N],ll[N],rr[N],p[N];int cnt;map<int,int > mp;struct person{    int l,a,no;}num[N];struct edge{    int v,next;}e[N];bool cmp(const person x,person y){    if(x.a!=y.a)    return x.a>y.a;    return x.no<y.no;}void init(){    cnt=0;    memset(head,-1,sizeof(head));}void addedge(int u,int v){    e[cnt].v=v;e[cnt].next=head[u];head[u]=cnt++;}void dfs(int x){    p[x]=cnt;    ll[x]=cnt;    for(int i=head[x];i!=-1;i=e[i].next){        cnt++;        dfs(e[i].v);    }    rr[x]=cnt;}void pushup(int rt){    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);}void build(int l,int r,int rt){    Max[rt]=0;    if(l==r){        return ;    }    int m=(l+r)>>1;    build(lson);    build(rson);}int query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R){        return Max[rt];    }    int m=(l+r)>>1;    if(R<=m)    return query(L,R,lson);    if(L>m)    return query(L,R,rson);    return max(query(L,R,lson),query(L,R,rson));}void update(int x,int i,int l,int r,int rt){  //  cout<<p[x]<<' '<<i<<' '<<l<<' '<<r<<' '<<rt<<endl;    if(l==r){        Max[rt]=num[i].l;        return ;    }    int m=(l+r)>>1;    if(p[x]<=m)    update(x,i,lson);    else    update(x,i,rson);    pushup(rt);}int main(){    int T,n,m,j,x;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        init();        for(int i=2;i<=n;i++){            scanf("%d",&j);            num[i].no=i;            scanf("%d%d",&num[i].l,&num[i].a);            mp[num[i].l] = i;            addedge(j+1,i);        }        cnt=1;        dfs(1);        build(1,n,1);        sort(num+2,num+1+n,cmp);        for(int i=2;i<=n;i++){            ans[num[i].no]=query(ll[num[i].no],rr[num[i].no],1,n,1);            if(ans[num[i].no]!=0){                ans[num[i].no]=mp[ans[num[i].no]];            }            update(num[i].no,i,1,n,1);        }        while(m--){            scanf("%d",&x);            printf("%d\n",ans[x+1]-1);        }    }    return 0;}


0 0
原创粉丝点击