Topic Link: http://acm.hdu.edu.cn/showproblem.php?pid=3308, simple line segment tree interval merging.
Interval merging of segment trees: it is generally required to find the longest continuous interval, and the interval merging operation is implemented in the Pushup () function.
Solution:
Because for the longest sequence of an interval, the optimal solution is either completely in the left half sequence or completely in the right half, or across the middle point. Therefore, the segment tree can be constructed to maintain three elements of the node interval: Longest ascending prefix len[].l, longest ascending suffix len[].r, longest ascending sequence len[].m. So for an interval, there are two things:
1. The rightmost value of the left son >= the leftmost value of the right son (no interval merging)
prefix = left son's prefix len[rt].l = len[rt << 1].l
suffix = right son suffix len[rt].r = len[rt << 1 | 1].r
Longest sequence = maximum value of the longest sequence of left and right sons LEN[RT].M = max (Len[rt << 1].m, len[rt << 1 | 1].m)
2. Left son rightmost value < right son leftmost value (can be combined by interval)
prefix = (prefix of left son = = length of left son)? Prefix of left son + prefix of right son: prefix of left son
suffix = (suffix of right son = = length of right son)? Suffix of right son + suffix of left son: suffix of right son
Longest sequence = max (suffix of left son + prefix of right son, longest sequence of left son, longest sequence of right son)
It is also important to note that the query () function, when queried, completely in the left half of the interval or completely in the right half of the interval is better to do, if it is on both sides of the case to consider:
1. The interval cannot be merged: this situation can directly return to the left and right son query maximum value can be;
2. The interval can be combined: The length of the son after the merger, the left and right of the son's query, the three to take the maximum value; It is important to note that the length of the query interval cannot be exceeded by merging the left and the son.
#include <iostream>#include<cstdio>#include<cmath>#include<queue>#include<vector>#include<string>#include<string.h>#include<algorithm>using namespacestd;#defineLL __int64#defineFlag A[m + 1] > A[m]//flag for interval merging#defineLson L, M, RT << 1#defineRson m + 1, R, RT << 1 | 1Const intMAXN =100000+5;structMax_len {//three elements intL, R, M;} LEN[MAXN<<2];intA[MAXN];voidPushup (intLintRintRT) {//implementation of interval merging in Pushup intm = (L + r) >>1; LEN[RT].L= Len[rt <<1].L; if(flag && LEN[RT].L = = (M-l +1)) Len[rt].l+ = Len[rt <<1|1].L; LEN[RT].R= Len[rt <<1|1].R; if(flag && LEN[RT].R = = (R-m)) LEN[RT].R+ = Len[rt <<1].R; if(flag) {LEN[RT].M= Max (Len[rt <<1].R + len[rt <<1|1].L, Max (Len[rt<<1].M, Len[rt <<1|1].m)); } Else{len[rt].m= Max (Len[rt <<1].M, Len[rt <<1|1].m); }}voidBuildintLintRintRT) { if(L = =r) {scanf ("%d", &A[l]); LEN[RT].L= LEN[RT].R = LEN[RT].M =1; return; } intm = (L + r) >>1; Build (Lson); Build (Rson); Pushup (L, R, RT);}voidUpdateintPintXintLintRintRT) { if(L = =R) {A[p]=x; return; } intm = (L + r) >>1; if(P <=m) Update (p, x, Lson); ElseUpdate (P, x, Rson); Pushup (L, R, RT);}intQueryintLintRintLintRintRT) { if(l <= l && R >=r) {returnlen[rt].m; } intm = (L + r) >>1; if(R <=m)returnquery (L, R, Lson); Else if(L >m)returnquery (L, R, Rson); Else { intLL =query (L, R, Lson); intRR =query (L, R, Rson); intRET =Max (LL, RR); if(flag) {ll= Min (len[rt <<1].R, M-l +1);//cannot exceed the length of the query intervalrr = min (len[rt <<1|1].L, R-m); RET= Max (ret, LL +RR); } returnret; }}intMain () {intN, M, T; intA, B; Charch[3]; CIN>>T; while(t--) {scanf ("%d%d", &n, &m); Build (0N1,1); while(m--) {scanf ("%s", CH); if(ch[0] =='U') {scanf ("%d%d", &a, &b); Update (A, B,0N1,1); } Else{scanf ("%d%d", &a, &b); printf ("%d\n", query (A, B,0N1,1)); } } } return 0;}
HDU3308 Segment Tree Interval merging