【HDU4366】【DFS序+分块】Successor

Problem Description
Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty and ability.Some times Sean will fire one staff.Then one of the fired man’s Subordinates will replace him whose ability is higher than him and has the highest loyalty for company.Sean want to know who will replace the fired man.
 

 

Input
In the first line a number T indicate the number of test cases. Then for each case the first line contain 2 numbers n,m (2<=n,m<=50000),indicate the company has n person include Sean ,m is the times of Sean’s query.Staffs are numbered from 1 to n-1,Sean’s number is 0.Follow n-1 lines,the i-th(1<=i<=n-1) line contains 3 integers a,b,c(0<=a<=n-1,0<=b,c<=1000000),indicate the i-th staff’s superior Serial number,i-th staff’s loyalty and ability.Every staff ‘s Serial number is bigger than his superior,Each staff has different loyalty.then follows m lines of queries.Each line only a number indicate the Serial number of whom should be fired.
 

 

Output
For every query print a number:the Serial number of whom would replace the losing job man,If there has no one to replace him,print -1.
 

 

Sample Input
1 3 2 0 100 99 1 101 100 1 2
 

 

Sample Output
2 -1
 

 

Author
FZU
【分析】
简单的DFS序题,DFS一下变成序列问题,预处理后块内二分就可以做了。
交上去一直RE,跟别人对拍了好像没错,不知道怎么回事......
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <vector>
  6 #include <utility>
  7 #include <iomanip>
  8 #include <string>
  9 #include <cmath>
 10 #include <queue>
 11 #include <assert.h>
 12 #include <map>
 13 
 14 const int N = 55555 + 10;
 15 const int SIZE = 250;//块状链表的大小 
 16 const int M = 50000 + 5;
 17 using namespace std;
 18 typedef long long ll;
 19 struct DATA {
 20     int a, b;
 21 }data[N], list[N], Sort[N];
 22 bool operator < (DATA a,DATA b) {
 23     return a.b < b.b;
 24 }
 25 map<int,int> Map;
 26 vector<int>G[N];
 27 int pos[N], tot, Max[N];
 28 int size[N], n, q;
 29 
 30 //二分搜索
 31 int search(int l, int r, int val){
 32     if (Sort[r].b <= val) return -1;
 33     if (Sort[l].b > val) return Max[l];
 34     while (l + 1 < r) {
 35         int mid = (l + r) >> 1;
 36         if (Sort[mid].b > val) r = mid; 
 37         else l = mid;
 38     }
 39     return Max[r];
 40 }
 41 int dfs(int u){
 42     pos[u] = tot;
 43     list[tot] = Sort[tot] = data[u];
 44     tot++;//tot为时间序 
 45     int cnt = 1;
 46     for (int i = 0; i < G[u].size(); i++){
 47         int v = G[u][i];
 48         cnt += dfs(v);
 49     }
 50     return size[pos[u]] = cnt;
 51 }
 52 
 53 void prepare(){
 54      memset(data, -1, sizeof(data));
 55      memset(Sort, -1, sizeof(Sort));
 56      memset(list, -1, sizeof(list));
 57      memset(Max, 0, sizeof(Max));
 58      memset(size, 0, sizeof(size));
 59      memset(pos, 0, sizeof(pos));
 60      scanf("%d%d", &n, &q);
 61      for (int i = 0; i < n; i++) G[i].clear();//初始化邻接表 
 62      Map.clear();
 63      Map[-1] = -1;
 64 }
 65 void init(){
 66      for (int i = 1; i < n; i++){
 67          int fa, x, y;
 68          scanf("%d%d%d", &fa, &x, &y);
 69          G[fa].push_back(i);
 70          data[i].a = x;
 71          data[i].b = y;
 72          Map[x] = i;
 73      }
 74      tot = 0;
 75      dfs(0);//构图 
 76 }
 77 void dp(){
 78       //预处理出每一个块内的值,好二分 
 79       for (int i = 0; i < n; i += SIZE){
 80           int j = i + SIZE;
 81           if (j > n) break;
 82           sort(Sort + i, Sort + j);
 83           Max[j - 1] = Sort[j - 1].a;
 84           //块内地推 
 85           for (int k = j - 2; k >= i;k--) Max[k] = max(Max[k + 1], Sort[k].a);
 86       } 
 87 }
 88 void query(int l, int r, int val){
 89      int ans = -1;
 90      for (int i = l; i <= r;){
 91          if (i % SIZE == 0 && i + SIZE - 1 <= r){
 92             int tmp = search(i, i + SIZE - 1, val);
 93             ans = max(ans, tmp);
 94             i += SIZE;
 95          }else{//暴力 
 96             if (list[i].b > val && list[i].a > ans) ans = list[i].a;
 97             i++;
 98          }
 99      }
100      //printf("%d\n", ans);
101      printf("%d\n", Map[ans]);
102 }
103 void work(){
104      for (int i = 1; i <= q; i++){
105          int x, val;
106          scanf("%d", &x);
107          val = data[x].b;
108          x = pos[x];
109          int y = x + size[x] - 1;//size用来存子树的大小
110          //printf("*%d*\n", y);
111          query(x, y, val);
112      } 
113 }
114 
115 int main(){
116     int T;
117     #ifdef LOCAL
118     freopen("data.txt", "r", stdin);
119     freopen("out.txt", "w", stdout);
120     #endif
121     scanf("%d", &T);
122     while (T--){
123           prepare();//初始化
124           init(); 
125           dp();
126           work(); 
127     }
128     return 0;
129 }
View Code

 

转载于:https://www.cnblogs.com/hoskey/p/4325012.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值