HDU 4123 Bob’s Race(RMQ)

题意是说给出一棵树,N(10^5)个顶点,以及每条边的权值,现在需要选择连续的K个点(顶点编号连续),可以被选出来的条件是:

若d[i]代表顶点i到树上其他点的距离的最大值,使得区间[a, b]的d值的最大差值不大于Q,

也就是max(d[a], d[a + 1], ..., d[b]) - max(d[a], d[a + 1], ..., d[b]) <= Q

Q是给出的一个查询(共有m<=500个查询),求对应每一个查询的K的最大值

思路是首先预处理出每个点到其他点的最大距离, 这可以通过两遍dfs算出来,然后对于每一个查询Q,找出一个最大长度的区间,使得这个区间的最大最小值差<=Q,所以还需要RMQ预处理出每个区间的最大值与最小值(这里查询需要做到O(1)),然后扫描一遍数组便可以得到这个最大长度的区间。

  1 #pragma comment(linker, "/STACK:1677721600")
  2 #include <map>
  3 #include <set>
  4 #include <stack>
  5 #include <queue>
  6 #include <cmath>
  7 #include <ctime>
  8 #include <vector>
  9 #include <cstdio>
 10 #include <cctype>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <iostream>
 14 #include <algorithm>
 15 using namespace std;
 16 #define INF 0x3f3f3f3f
 17 #define inf (-((LL)1<<40))
 18 #define lson k<<1, L, (L + R)>>1
 19 #define rson k<<1|1,  ((L + R)>>1) + 1, R
 20 #define mem0(a) memset(a,0,sizeof(a))
 21 #define mem1(a) memset(a,-1,sizeof(a))
 22 #define mem(a, b) memset(a, b, sizeof(a))
 23 #define FIN freopen("in.txt", "r", stdin)
 24 #define FOUT freopen("out.txt", "w", stdout)
 25 #define rep(i, a, b) for(int i = a; i <= b; i ++)
 26 #define dec(i, a, b) for(int i = a; i >= b; i --)
 27
 28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
 29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
 30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
 31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
 32
 33 //typedef __int64 LL;
 34 typedef long long LL;
 35 const int MAXN = 50000 + 100;
 36 const int MAXM = 110000;
 37 const double eps = 1e-8;
 38 LL MOD = 1000000007;
 39
 40 struct Node {
 41     int v, s;
 42     Node(int _v = 0, int _s = 0) {
 43         v = _v; s = _s;
 44     }
 45 };
 46
 47 vector<Node>G[MAXN];
 48 int mx[MAXN], se[MAXN], d[MAXN], idx[MAXN];
 49 int ma[MAXN][20], mi[MAXN][20];
 50 int n, u, v, w;
 51 int m, Q;
 52
 53 void init(int n) {
 54     rep (i, 0, n) G[i].clear();
 55     mem0(mx); mem0(se);
 56 }
 57
 58 void dfs1(int u, int fa) {
 59     mx[u] = se[u] = 0;
 60     int sz = G[u].size();
 61     rep (i, 0, sz - 1) {
 62         int v = G[u][i].v;
 63         if(v == fa) continue;
 64         dfs1(v, u);
 65         int len = G[u][i].s + mx[v];
 66         if(len > mx[u]) se[u] = mx[u], mx[u] = len;
 67         else if(len > se[u]) se[u] = len;
 68     }
 69 }
 70
 71 void dfs2(int u, int fa, int dis) {
 72     d[u] = max(dis, max(mx[u], se[u]));
 73     int sz = G[u].size();
 74     rep (i, 0, sz - 1) {
 75         int v = G[u][i].v, len = G[u][i].s;
 76         if(v == fa) continue;
 77         if(len + mx[v] == mx[u])
 78             dfs2(v, u, max(dis, se[u]) + len);
 79         else
 80             dfs2(v, u, max(dis, mx[u]) + len);
 81     }
 82 }
 83
 84 void rmq_init(int n) {
 85     rep (i, 1, n) ma[i][0] = mi[i][0] = d[i];
 86     for(int j = 1; (1<<j) <= n; j ++) {
 87         for(int i = 1; i + (1<<j) - 1 <= n; i ++) {
 88             ma[i][j] = max(ma[i][j - 1], ma[i + (1 << (j - 1))][j - 1]);
 89             mi[i][j] = min(mi[i][j - 1], mi[i + (1 << (j - 1))][j - 1]);
 90         }
 91     }
 92     rep (len, 1, n) {
 93         idx[len] = 0;
 94         while((1 << (idx[len] + 1)) <= len) idx[len] ++;
 95     }
 96 }
 97
 98 int rmq(int l, int r) {
 99     int k = idx[r - l + 1];
100     return max(ma[l][k], ma[r - (1 << k) + 1][k]) - min(mi[l][k], mi[r - (1 << k) + 1][k]);
101 }
102
103 int main()
104 {
105 //    FIN;
106     while(~scanf("%d %d", &n, &m) && n) {
107         init(n);
108         rep (i, 1, n - 1) {
109             scanf("%d %d %d", &u, &v, &w);
110             G[u].push_back(Node(v, w));
111             G[v].push_back(Node(u, w));
112         }
113
114         //计算每个点到叶子节点的最远距离
115         dfs1(1, -1);
116         dfs2(1, -1, 0);
117
118         //计算答案
119         rmq_init(n);
120         while(m --) {
121             scanf("%d", &Q);
122             int l = 1, ans = 0;
123             rep (i, 1, n) {
124                 while(l < i && rmq(l, i) > Q) l ++;
125                 ans = max(ans, i - l + 1);
126             }
127             cout << ans << endl;
128         }
129     }
130     return 0;
131 }
时间: 2024-10-29 19:05:48

HDU 4123 Bob’s Race(RMQ)的相关文章

hdu 4123 Bob’s Race (树的直径相关+rmq+单调队列思想)

Bob's Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2115    Accepted Submission(s): 658 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble

hdu 4123 Bob’s Race(树形dp+RMQ)

题目链接:hdu 4123 Bob's Race 题目大意:一个城镇有N个住户,N-1条路连接两个住户,保证N个住户联通,M次询问,给定N条边的信息,包括连 接的住户序号以及路的长度.然后是M次询问,每次询问Q,要求找到最长的连续序号,使得Max(dis[i]) - Min(dis[i]) ≤ Q(l≤i≤r),输出最大的r-l+1.dis[i]为从第i个住户出发,不重复走过路能移动的最远距离. 解题思路:树形dp,通过两次dfs,第1次处理出每个节点中孩子节点移动的最长距离和第二长距离,第2次

hdu 3183 A Magic Lamp(RMQ)

A Magic Lamp                                                                               Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Kiki likes traveling. One day she finds a magic lamp, u

HDU 4123 Bob&#39;s Race:单调队列 + st表

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 题意: 给你一棵树,n个节点,每条边有长度. 然后有m个询问,每个询问给定一个q值. 设dis[i]为:从节点i出发,不重复经过节点,所能够走的最远距离. 每次询问问你:区间[l,r]最长能有多长,同时保证 max{dis[i]} - min{dis[i]} <= q (i∈[l,r]) 题解: 首先有一个结论: 从树上的任意一个节点出发,尽可能往远走,最终一定会到达树的直径的两个端点之一.

HDOJ 题目4123 Bob’s Race(树的直径+RMQ优化)

Bob's Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2753    Accepted Submission(s): 888 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble

hdu 4123 Bob’s Race 树的直径+rmq+尺取

Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads

HDU 4123 Bob’s Race

Bob’s Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4123 Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads

HDU 4123 Bob’s Race 树的直径+单调队列

题意: 给定n个点的带边权树Q个询问. 下面n-1行给出树 下面Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列使得序列中最大值-最小值 <= u,输出这个序列的长度. 思路: 求dp数组就是求个树的直径然后dfs一下. 对于每个询问,可以用一个单调队列维护一下.O(n)的回答. #include <cstdio> #include <cstring> #include <strin

hdu 5640 King&#39;s Cake(模拟)

Problem Description It is the king's birthday before the military parade . The ministers prepared a rectangle cake of size n×m(1≤n,m≤10000) . The king plans to cut the cake himself. But he has a strange habit of cutting cakes. Each time, he will cut