• hdu 4366 Successor (线段树 2012 MultiUniversity Training Contest 7 )


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

    题意:

    给你 n个点。他们有 上下级关系,一个点只有一个上级,一个上级 可以有多个下级,每个点有两个属性,能力值 、忠诚度(每个节点的忠诚度不同),求我们要删除 一个节点, 则我们 需从 其下级中选出 一个节点,其能力值 比该节点 要高,且 忠诚度是(比其能力高的下级节点中的)最高

    题解:

    首先将树状结构,转化为 线状结构,

    可以遍历一遍将树上每个点标记为一维区间上的某个点,且在同一棵子树内的点是连续的一段。

    然后,将所有点按能力从大到小排序,能力相同的编号小的排在前面,然后扫描一遍,扫描时维护一颗线段树,

    (我们先插入线段树的是,比其能力值 大的,我们只要从这些里面找到,忠诚度最高的就 可以了)

    先查找该点为根节点的子树内的最优值,然后插入该点的忠诚度。

      1 #include<stdio.h>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<queue>
      7 #include<set>
      8 #include<map>
      9 #define Min(a,b)  a>b?b:a
     10 #define Max(a,b)  a>b?a:b
     11 #define CL(a,num)  memset(a,num,sizeof(a));
     12 #define inf 9999999
     13 #define maxn    100110
     14 #define mod 100000007
     15 #define eps  1e-6
     16 #define ll  long long
     17 #define M   15520
     18 using namespace std;
     19 map<int,int>map1;
     20 vector<int>g[maxn] ;
     21 int num ,ans[maxn],n,m,l[maxn],r[maxn];
     22 struct staff
     23 {
     24     int loy;
     25     int abt;
     26     int id;
     27 }sta[maxn];
     28 struct node
     29 {
     30     int l;
     31     int r;
     32     int mx;
     33 }p[maxn * 2];
     34 bool cmp (staff a, staff b)
     35 {
     36     return a.abt > b.abt ;
     37 }
     38 void dfs(int x)//编号变为线状结构
     39 {
     40 
     41     l[x] = num++;
     42     for(int i = 0; i < g[x].size(); ++i)
     43     {
     44         dfs(g[x][i]);
     45     }
     46 
     47     r[x] = num ;
     48 
     49 }
     50 void build(int x,int l,int r)
     51 {
     52     p[x].l = l;
     53     p[x].r = r;
     54     p[x].mx = -1 ;
     55     if(l == r) return  ;
     56     int mid = (l + r) /2;
     57     build(x*2,l,mid);
     58     build(x*2+1,mid + 1,r);
     59 
     60 }
     61 int get(int x,int l,int r)
     62 {
     63 
     64     if( r < l ) return  -1 ;
     65     if(p[x].l == l && p[x].r == r)
     66     {
     67 
     68         return p[x].mx;
     69     }
     70     int mid = (p[x].l + p[x].r) /2 ;
     71     if(r <= mid)  return get(x * 2,l,r);
     72     else
     73     {
     74         if(l > mid) return get(x * 2 + 1,l,r);
     75         else
     76         {
     77             return max(get(x * 2,l,mid),get(x * 2 + 1,mid + 1,r));
     78         }
     79     }
     80 }
     81 void insert(int x,int pos,int d)
     82 {
     83     if(p[x].l == p[x].r )
     84     {
     85         p[x].mx = d;
     86         return ;
     87 
     88     }
     89     int mid = (p[x].l + p[x].r) /2 ;
     90     if(pos <= mid) insert(x*2,pos,d);
     91     else
     92     {
     93        insert(x*2 + 1, pos,d);
     94 
     95     }
     96 
     97     p[x].mx = max(p[x*2].mx,p[x*2+1].mx);
     98 
     99 }
    100 void init()
    101 {
    102      forint i = 0; i <= n;++i )
    103           g[i].clear();
    104 
    105     map1.clear();
    106 
    107     num = 0 ;
    108 }
    109 int main()
    110 {
    111     int t,u,loy,abt,a,j,i;
    112     scanf("%d",&t);
    113     while(t--)
    114     {
    115         scanf("%d%d",&n,&m);
    116         init();
    117 
    118         for( i = 1 ; i < n;++i)
    119         {
    120             scanf("%d%d%d",&u,&loy,&abt);
    121             g[u].push_back(i);
    122             sta[i].loy = loy;
    123             sta[i].abt = abt ;
    124             sta[i].id = i;
    125             map1[loy] = i;
    126 
    127         }
    128 
    129         dfs(0);
    130 
    131         build(1,0,num - 1);
    132         sort(sta + 1,sta + n,cmp);//排序为了下面 查询 打基础,排好序之后,我们插入时,保证了,比 i 大的已经插入了这时直接找,忠诚的uida就可以了
    133 
    134 
    135         for( i = 1 ; i < n ;i = j)
    136         {
    137                j = i;
    138 
    139             while(j < n &&sta[i].abt == sta[j].abt)
    140             {
    141                 int id = sta[j].id ;
    142                 loy = get(1,l[id] + 1,r[id] - 1);
    143 
    144                 if(loy != -1) ans[id] = map1[loy] ;
    145                 else ans[id] = -1;
    146 
    147                 ++j;
    148 
    149             }
    150 
    151                   j = i ;
    152             while(j < n && sta[i].abt == sta[j].abt )
    153             {
    154                 int id =  sta[j].id;
    155                 insert(1,l[id],sta[j].loy);
    156                 ++j;
    157             }
    158 
    159 
    160 
    161         }
    162         while(m--)
    163         {
    164             scanf("%d",&a);
    165 
    166             printf("%d\n",ans[a]) ;
    167         }
    168     }
    169 
    170 }

  • 相关阅读:
    最近面试有感,不要耍小聪明,面试官都是开了上帝视角的
    Mac OS X上编写 ASP.NET vNext 系列中断和再开声明
    Mac OS X 上编写 ASP.NET vNext (二) IDE配置
    Mac OS X上编写 ASP.NET vNext(一)KRE环境搭建
    Redhat Linux /etc/profile 与 /etc/bashrc 的区别
    IIS7 Application Pool Integrate Mode 和 Classic Mode 的区别
    Linux 学习笔记(一) 入门
    SQL Server 常用分页SQL
    winform 如何控制输入法
    winform 记录全局异常捕获
  • 原文地址:https://www.cnblogs.com/acSzz/p/2643410.html
Copyright © 2020-2023  润新知