hdu 4366

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36651153/article/details/81458207

用dfs转化为区间

用线段树维护忠诚度

对能力进行排序 大的优先

因为题目要求忠诚度最高且能力比他大

先建大的,再建小的,小的就被push_up了

代码如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=50020;
int ha[1000020],ma[maxn*4],pre,cnt,s[maxn],e[maxn],ans[maxn],k,t,n,m;
struct Node
{
    int L,A,num;
}S[maxn];
vector<int> v[maxn];
void dfs(int i)
{
    s[i]=++cnt;
    for(int j=0;j<v[i].size();j++) {
        dfs(v[i][j]);
    }
    e[i]=cnt;
}
void Build(int o,int l,int r)
{
    ma[o]=-1;
    if(l==r) {
        return ;
    }
    int mid=l+r>>1;
    Build(o<<1,l,mid);
    Build(o<<1|1,mid+1,r);
}
bool cmp(Node a,Node b)
{
    return a.A>b.A;
}
void Update(int o,int l,int r,int v,int x)
{
    if(l==r) {
        ma[o]=v; return ;
    }
    int mid=l+r>>1;
    if(x<=mid) {
        Update(o<<1,l,mid,v,x);
    }
    else{
        Update(o<<1|1,mid+1,r,v,x);
    }
    ma[o]=max(ma[o<<1],ma[o<<1|1]);
}
int Query(int o,int l,int r,int x,int y)
{
    if(x>y) {
        return -1;
    }
    int ans=-1;
    if(x<=l&&r<=y) {
        return ma[o];
    }
    int mid=l+r>>1;
    if(x<=mid) {
        ans=max(ans,Query(o<<1,l,mid,x,y));
    }
    if(y>mid) {
        ans=max(ans,Query(o<<1|1,mid+1,r,x,y));
    }
    return ans;
}
int main()
{
    scanf("%d",&t);
    while(t-- ){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++) {
            v[i].clear();
        }
        for(int i=1;i<n;i++) {
            scanf("%d%d%d",&pre,&S[i].L,&S[i].A);
            v[pre].push_back(i);
            ha[S[i].L]=i; S[i].num=i;
        }
        cnt=0;
        dfs(0);
        Build(1,1,n-1);
        sort(S+1,S+n,cmp);
        int i=1,j;
        while(i<n) {
            j=i;
            while(j<n&&S[i].A==S[j].A) {
                k=Query(1,1,n-1,s[S[j].num],e[S[j].num]-1);
                printf("%d\n",k);
                if(k==-1) {
                    ans[S[j].num]=-1;
                }
                else{
                    ans[S[j].num]=ha[k];
                }
                j++;
            }
            j=i;
            while(j<n&&S[i].A==S[j].A) {
                Update(1,1,n-1,S[j].L,s[S[j].num]-1);
                j++;
            }
            i=j;
        }
        while(m--) {
            scanf("%d",&k);
            printf("%d\n",ans[k]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36651153/article/details/81458207