【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 }

时间: 2024-10-25 19:20:28

【HDU4366】【DFS序+分块】Successor的相关文章

HDU - 4366 Successor DFS序 + 分块暴力 or 线段树维护

给定一颗树,每个节点都有忠诚和能力两个参数,随意指定一个节点,要求在它的子树中找一个节点代替它,这个节点要满足能力值大于它,而且是忠诚度最高的那个. 首先,dfs一下,处理出L[i], R[i]表示dfs序,则R[i] - L[i] + 1 就是当前i这个节点拥有的子孙个数. 对于一颗树,dfs的时候,访问节点有先后顺序,那么可以用一个struct node List[maxn];表示这课树中访问的先后顺序. 例如这颗树,我假设是先访问0 --> 3 --> 2 ---> 4 ---&g

HDU 4366 Successor( DFS序+ 线段树 )

Successor Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2631    Accepted Submission(s): 634 Problem Description Sean owns a company and he is the BOSS.The other Staff has one Superior.every st

[ACM-ICPC 2018 沈阳网络赛] Ka Chang (dfs序+树状数组+分块)

Given a rooted tree ( the root is node 11 ) of NN nodes. Initially, each node has zero point. Then, you need to handle QQ operations. There're two types: 1\ L\ X1 L X: Increase points by XX of all nodes whose depth equals LL ( the depth of the root i

ACM-ICPC 2018 沈阳赛区网络预赛 J. Ka Chang(树上分块+dfs序+线段树)

题意 链接:https://nanti.jisuanke.com/t/A1998 给出一个有根树(根是1),有n个结点.初始的时候每个结点的值都是0.下面有q个操作,操作有两种,操作1.将深度为L(根节点深度为0)的点的值全部增加X.操作2.查询以x为根的子树的结点值得和.其中N,Q<=1e5. 思路 因为这题是对某一深度的所有点加x,所以不是树链剖分. 我们可以先预处理一下dfs序,顺带把d[u]:u的深度.dd[x]:深度为x的点集求出来. 考虑分块,对某一深度分两种情况:1.这一深度的点的

2016-5-21 letwetell Round3 (百度之星初赛,dfs序)

halfapri(- o -)Y { 1.2016百度之星Round2A 题目链接 题解链接 1001 All X 循环节 1002 Sitting in Line 状压dp 1003 Snacks 1004 D Game 1005 BD String 找规律 1006 Gym Class 贪心+topo 2.2012多校第7场 hdu4366 Successor 线段树 + dfs序 }

HDU 6203 ping ping ping(dfs序+LCA+树状数组)

http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意: n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连通.问无法通行的点最少有多少个. 思路: 贪心思维,破坏两个点的LCA是最佳的.那么怎么判断现在在(u,v)之间的路径上有没有被破坏的点呢,如果没有的话那么此时就要破坏这个lca点.一开始我们要把询问按照u和v的lca深度从大到小排序,如果某个点需要被破坏,那么它的所有子节点都可以不再需要破坏别的点

【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高速光缆组成.每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络.该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信. 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略.但是由于路由器老化,在这些

BZOJ2434 NOI2011 阿狸的打字机 AC自动机+树状数组+DFS序

题意:给定三个操作:1.在当前字符串的末尾添加一个字符c  2.在当前字符串的末尾删除一个字符  3.记录当前字符串并对其标号.再给出N组询问,每组询问需回答第x个字符串在第y个字符串中出现的次数 题解: 首先按照如下规则建Trie,设当前节点为t,第i个字符串的结尾在Trie中的位置为mark[i]: 1.插入操作:看t是否有c这个儿子,有则t=t->child[c],否则t->child[c]=NewNode,t=t->child[c] 2.删除操作:t=t->father 3

【Codeforces163E】e-Government AC自动机fail树 + DFS序 + 树状数组

E. e-Government time limit per test:1 second memory limit per test:256 megabytes input:standard input output:standard output The best programmers of Embezzland compete to develop a part of the project called "e-Government" — the system of automa