Poj 3162 line segment tree hdu 4123 bfs + RMQ preprocessing

Source: Internet
Author: User

Give you a tree and mark it as 1 ~ N, each edge has a certain edge weight, so there is a maximum distance from each vertex num [I];
First obtain the num [] array, and then there are 500 more queries. For each query, enter an integer m, evaluate the maximum and minimum values in the num array. The difference between the absolute values of the maximum and minimum values does not exceed the maximum continuous interval of m.

This is the topic of the 2011 Fuzhou semi-finals. It is really a big question. poj also has a similar question. It should be said that it was adapted.
Okay. Let's talk about how I did it.
1: We first pre-process the num Array Using the tree's longest path.
2
3: O (n) can be used to answer each query and maintain two pointers (l). If the current range meets the condition r ++, otherwise l ++, each point is inserted and deleted once, and the query with the highest range value is O (1), so the complexity of the query is
Q * n is 500*50000.
The total complexity is nlog (n) + q * n
So it's the complexity of q * n, that is, 500*50000. The time limit is two seconds. It's easy ~

[Cpp]
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
Using namespace std;
Const int inf = ~ 0u> 2;
Const int maxn = 50010;
Int n, m;
Struct Edge {
Int v, w, next;
} Edge [2 * maxn];
Int head [maxn], E, num [maxn];
Void add_edge (int a, int B, int w)
{
Edge [E]. v = B;
Edge [E]. w = w;
Edge [E]. next = head [a];
Head [a] = E ++;
}
Int dis1 [maxn], dis2 [maxn];
Bool vis [maxn];
Int q [maxn];
Void bfs (int s, int & ss, int dist []) {
Fill (dist, dist + n + 1, inf );
Fill (vis, vis + n + 1, false );
Vis [s] = true;
Dist [s] = 0;
Int front (0), tail (0), u, v, w;
Q [0] = s; int Max = 0;
While (front <= tail ){
U = q [front ++];
For (int I = head [u]; I! =-1; I = edge [I]. next ){
V = edge [I]. v, w = edge [I]. w;
If (vis [v]) continue;
Vis [v] = true;
Dist [v] = dist [u] + w;
If (dist [v]> Max ){
Max = dist [v];
Ss = v;
}
Q [++ tail] = v;
}
}
}
Int LOG [2 * maxn];
Int dp1 [20] [2 * maxn];
Int dp2 [20] [2 * maxn];
Inline int min (int a, int B ){
Return a <B? A: B;
}
Inline int max (int a, int B ){
Return a> B? A: B;
}
Void rmq_init (int n)
{
Int I, j;
For (j = 1; j <= n; j ++ ){
Dp1 [0] [j] = num [j];
Dp2 [0] [j] = num [j];
}
For (j = 1; j <= LOG [n]; j ++ ){
Int limit = n + 1-(1 <j );
For (I = 1; I <= limit; I ++ ){
Int x = I + (1 <j> 1 );
Dp1 [j] [I] = min (dp1 [J-1] [x], dp1 [J-1] [I]);
Dp2 [j] [I] = max (dp2 [J-1] [x], dp2 [J-1] [I]);
}
}
}
Int rmq_min (int l, int r)
{
Int m = LOG [r-l + 1];
Return min (dp1 [m] [l], dp1 [m] [r-(1 <m) + 1]);
}
Int rmq_max (int l, int r)
{
Int m = LOG [r-l + 1];
Return max (dp2 [m] [l], dp2 [m] [r-(1 <m) + 1]);
}
Int main ()
{
Int q;
LOG [0] =-1;
For (int I = 1; I <2 * maxn; I ++) LOG [I] = LOG [I> 1] + 1;
While (scanf ("% d", & n, & q), n | q)
{
E = 0; fill (head, head + n + 1,-1 );
For (int I = 2, a, B, w; I <= n; I ++)
{
Scanf ("% d", & a, & B, & w );
Add_edge (a, B, w );
Add_edge (B, a, w );
}
Int ss, tt;
Bfs (1, ss, dis1 );
Bfs (ss, tt, dis1 );
Bfs (tt, ss, dis2 );
For (int I = 1; I <= n; I ++) num [I] = max (dis1 [I], dis2 [I]);
Rmq_init (n );
While (q --){
Scanf ("% d", & m );
Int ans = 0;
Int l = 1, r = 1, mx, mi;
While (r <= n ){
Mx = rmq_max (l, r );
Mi = rmq_min (l, r );
If (mx-mi <= m ){
Ans = max (ans, r-l + 1 );
R ++;
}
Else l ++;
}
Printf ("% d \ n", ans );
}
}
Return 0;
}

Http://poj.org/problem? Id = 3162
Poj 3162 has points. The RMQ space cannot be opened, so we can only query the maximum value of a line segment tree. The complexity is n * log (n ), discuss said there are still O (n) practices, which seem to be monotonous queue practices. No, so I will post them later.
C ++ ran more than 5 S

[Cpp]
# Include <cstdio>
# Include <set>
# Include <cstring>
# Include <algorithm>
Using namespace std;
# Define lson l, m, rt <1
# Define rson m + 1, r, rt <1 | 1
Const int inf = ~ 0u> 2;
Const int maxn = 1000010;
Int n, m;
Struct Edge {
Int v, w, next;
} Edge [2 * maxn];
Int head [maxn], E, num [maxn];
Void add_edge (int a, int B, int w)
{
Edge [E]. v = B;
Edge [E]. w = w;
Edge [E]. next = head [a];
Head [a] = E ++;
}
Int dis1 [maxn], dis2 [maxn];
Bool vis [maxn];
Int q [maxn];
Void bfs (int s, int & ss, int dist []) {
Fill (dist, dist + n + 1, inf );
Fill (vis, vis + n + 1, false );
Vis [s] = true;
Dist [s] = 0;
Int front (0), tail (0), u, v, w;
Q [0] = s; int Max = 0;
While (front <= tail ){
U = q [front ++];
For (int I = head [u]; I! =-1; I = edge [I]. next ){
V = edge [I]. v, w = edge [I]. w;
If (vis [v]) continue;
Vis [v] = true;
Dist [v] = dist [u] + w;
If (dist [v]> Max ){
Max = dist [v];
Ss = v;
}
Q [++ tail] = v;
}
}
}
Inline int min (int a, int B ){
Return a <B? A: B;
}
Inline int max (int a, int B ){
Return a> B? A: B;
}
Int mx [maxn <2], mi [maxn <2];
Void pushup (int rt ){
Mx [rt] = max (mx [rt <1], mx [rt <1 | 1]);
Mi [rt] = min (mi [rt <1], mi [rt <1 | 1]);
}
Void build (int l, int r, int rt ){
If (l = r ){
Mx [rt] = mi [rt] = num [l];
Return;
}
Int m = (l + r)> 1;
Build (lson );
Build (rson );
Pushup (rt );
}
Int find_min (int L, int R, int l, int r, int rt)
{
If (L <= l & r <= R)
{
Return mi [rt];
}
Int m = (l + r)> 1;
Int ret = inf;
If (L <= m) ret = min (ret, find_min (L, R, lson ));
If (R> m) ret = min (ret, find_min (L, R, rson ));
Return ret;
}
Int find_max (int L, int R, int l, int r, int rt)
{
If (L <= l & r <= R)
{
Return mx [rt];
}
Int m = l + r> 1;
Int ret = 0;
If (L <= m) ret = max (ret, find_max (L, R, lson ));
If (R> m) ret = max (ret, find_max (L, R, rson ));
Return ret;
}
Int main ()
{
Scanf ("% d", & n, & m );
E = 0; fill (head, head + n + 1,-1 );
For (int I = 2, fa, w; I <= n; I ++)
{
Scanf ("% d", & fa, & w );
Add_edge (I, fa, w );
Add_edge (fa, I, w );
}
Int ss, tt;
Bfs (1, ss, dis1 );
Bfs (ss, tt, dis1 );
Bfs (tt, ss, dis2 );
For (int I = 1; I <= n; I ++)
{
Num [I] = max (dis1 [I], dis2 [I]);
}
Int l = 1, r = 1, mx, mi;
Int ans = 0;
Build (1, n, 1 );
While (r <= n)
{
Mx = find_max (l, r, 1, n, 1 );
Mi = find_min (l, r, 1, n, 1 );
If (mx-mi <= m)
{
Ans = max (ans, r-l + 1 );
R ++;
}
Else {

L ++;
}
}
Printf ("% d \ n", ans );
Return 0;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.