hdu 4366 Successor

http://acm.hdu.edu.cn/showproblem.php?pid=4366

线段树

题意是要找某个点其子孙中能力值其能力值的中忠诚度最大的。

首先可以遍历一遍将树上每个点标记为一维区间上的某个点,且在同一棵子树内的点是连续的一段。将所有点按能力从大到小排序,能力相同的编号小的排在前面,然后扫描一遍,扫描时维护一颗线段树,先查找该点为根节点的子树内的最优值,然后插入该点的忠诚度。维护区间的最大忠诚值就行了。

 

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<utility>
 6 using namespace std;
 7 const int maxn = 50010;
 8 const int N = 1000005;
 9 struct nd{
10     int v,next;
11 }edge[maxn];
12 int p[maxn],ls[maxn][2],lo[maxn],Hash[N],ab[maxn],id[maxn];
13 int as[maxn<<2],ans[maxn];
14 int n,m,ecnt,idx;
15 void add(int u,int v)
16 {
17     edge[ecnt].v = v;
18     edge[ecnt].next = p[u];
19     p[u] = ecnt++;
20 }
21 bool cmp(int a,int b)
22 {
23     if(ab[a]^ab[b])return ab[a] > ab[b];
24     return a < b;
25 }
26 void getlist(int x)
27 {
28     ls[x][0] = idx++;
29     for(int i = p[x]; ~i; i = edge[i].next)
30     getlist(edge[i].v);
31     ls[x][1] = idx - 1;
32 }
33 void readin()
34 {
35     int i,a;
36     scanf("%d %d",&n,&m);
37     ecnt = 0;
38     memset(p,-1,sizeof(p));
39     for(i = 1; i < n; ++ i){
40         scanf("%d %d %d",&a,lo+i,ab+i);
41         id[i] = i;
42         Hash[lo[i]] = i;
43         add(a,i);
44     }
45     idx = 0;
46     sort(id+1,id+n,cmp);
47     getlist(0);
48 }
49 void update(int rt,int l,int r,int L,int val)
50 {
51     int mid = (l + r) >> 1;
52     if(l==r){
53         as[rt] = val;
54         return;
55     }
56     if(L<=mid)update(rt<<1,l,mid,L,val);
57     else update(rt<<1|1,mid+1,r,L,val);
58     as[rt] = max(as[rt<<1],as[rt<<1|1]);
59 }
60 int ret;
61 void query(int rt,int l,int r,int L,int R)
62 {
63     int mid = (l + r) >> 1;
64     if(L<=l && r<= R){
65         ret = max(ret,as[rt]);
66         return;
67     }
68     if(L<=mid)query(rt<<1,l,mid,L,R);
69     if(R>mid)query(rt<<1|1,mid+1,r,L,R);
70 }
71 void processing()
72 {
73     memset(as,-1,sizeof(as));
74     for(int i = 1; i < n; ++ i){
75         ret = -1;
76         if(ls[id[i]][0]^ls[id[i]][1])
77         query(1,1,n,ls[id[i]][0],ls[id[i]][1]);
78         if(~ret)ans[id[i]] = Hash[ret];
79         else ans[id[i]] = -1;
80         update(1,1,n,ls[id[i]][0],lo[id[i]]);
81     }
82     while(m--){
83         scanf("%d",&idx);
84         printf("%d\n",ans[idx]);
85     }
86 }
87 int main()
88 {
89     int T;
90     for(scanf("%d",&T);T--;){
91         readin();
92         processing();
93     }return 0;
94 }

 

 

posted on 2012-08-18 19:16  aigoruan  阅读(182)  评论(0)    收藏  举报

导航