zoukankan      html  css  js  c++  java
  • 【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
    ", ans);
    101      printf("%d
    ", 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*
    ", 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
  • 相关阅读:
    Linux中的官方源、镜像源汇总
    提示"libc.so.6: version `GLIBC_2.14' not found"
    win8.1 安装msi软件出现 2503、2502
    平均负载(Load average)
    oracle 导入报错:field in data file exceeds maximum length
    一个命令的输出作为另外一个命令的输入
    Http 状态码
    Linux 命令总结
    ORA-12505: TNS: 监听程序当前无法识别连接描述符中所给出的SID等错误解决方法
    轻松应对IDC机房带宽突然暴涨问题
  • 原文地址:https://www.cnblogs.com/hoskey/p/4325012.html
Copyright © 2011-2022 走看看