hdu 4366 线段树+dfs序列

#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<map>
#include<algorithm>
#define MS(x,y) memset(x,y,sizeof(x))
#define pi acos(-1.0)
#define ls o<<1
#define rs o<<1|1
#define root 1,0,time-1
using namespace std;
void fre(){freopen("t.txt","r",stdin);}
typedef long long LL;
typedef unsigned long long ULL;
const int MAXN = 50005;
const int inf = 0x3f3f3f3f;
struct staff
{
    int l,a,id;
}st[MAXN];
struct node
{
    int v,next;
}e[MAXN];

int m,n,ed,time;
int head[MAXN],in[MAXN*2],out[MAXN*2],ans[MAXN],maxv[8*MAXN];
map<int,int>mp;

bool cmp(staff a,staff b)
{
    return a.a > b.a;
}
void dfs(int x)
{
    in[x] = time++;
    for(int i = head[x]; i!=-1; i=e[i].next)
    {
        dfs(e[i].v);
    }
    out[x] = time++;
}
void init()
{
    int fa;
    ed = time = 0;
    MS(head,-1);MS(ans,-1);MS(maxv,-1);
    mp.clear();
    for(int i = 1; i < n; ++i)
    {
        scanf("%d%d%d",&fa,&st[i].l,&st[i].a);
        st[i].id = i;
        mp[st[i].l] = i;
        e[ed].v = i;
        e[ed].next = head[fa];
        head[fa] = ed++;
    }
    dfs(0);
    sort(st+1,st+n,cmp);
}
int query(int ql,int qr,int o,int l,int r)
{
    if(ql <= l && qr >= r) return maxv[o];
    int m = l+(r-l)/2,ans = -1;
    if(ql<= m) ans = query(ql,qr,ls,l,m);
    if(qr > m) ans = max(query(ql,qr,rs,m+1,r),ans);
    return ans;
}
void update(int p,int v,int o,int l,int r)
{
    if(l==r) maxv[o] = v;
    else
    {
        int m = l+(r-l)/2;
        if(p <= m) update(p,v,ls,l,m);
        else update(p,v,rs,m+1,r);
        maxv[o] = max(maxv[ls],maxv[rs]);
    }
}
int solve()
{
    int f;
    for(int i = 1; i <= m; ++i)
    {
        scanf("%d",&f);
        if(ans[f]==-1) printf("-1\n");
        else printf("%d\n",mp[ans[f]]);
    }
}
int main()
{
    // fre();
    int i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        init();

        for(i = 1; i < n; i = j)
        {
            j = i;
            while(j < n && st[i].a == st[j].a)//能力值相等,成一批
            {
                int id = st[j].id;
                ans[id] = query(in[id]+1,out[id]-1,root);
                j++;
            }
            j = i;
            while(j < n && st[i].a == st[j].a)
            {
                int id = st[j].id;
                update(in[id],st[j].l,root);
                j++;
            }
        }
        solve();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值