title:hdu-1540 Line Tree Brush problem
Date:2018-10-18 19:55:21
Tags
- Acm
- Brush questions
Categories
- acm-segment Tree
Overview
Wow, this line tree is the hardest thing I've ever done so far. Qaq,,,,,,
First read the problem is a face,,,, completely do not know where to start,,, is to know that this is a line of the tree and do not know how to do ah ah,,,,
Finally, I saw the code of the Kaungbin,,, Qaq
It took one or two hours to read the code, (but it could also be about the thief today, and the head doesn't turn.
Analytical Thinking test Instructions
The approximate test instructions is a string of villages on a line, or point,,, starting with 1,, and then there are three different operations,,,
- D A: It means to place a this point at 0,,,
- Q A: It means to ask how many 1 around a,,, as long as it touches 0 not forget,,, such as 110111110,, (q 5) = 5
- R: means to place the previous zero point at 1
Analyze my thoughts.
At first I saw that there was a need for the last operation, and thought to save these d operations, which is the stack for this problem,
Then I asked,,, I thought that since I asked for a number of these 1, then I found the two ends of the 0 not on the line,, and then from here on the thorough brain pumping,, and think of the line tree to seek this interval and,,, and then the result is obvious,,,, T,,,
Because,, this idea line segment tree does not use AH!!!! Find out where the two ends of the 0 location directly minus the line,,, this is not naked violence,,,, Wow,,, was himself stupid cry (?????????),,,,
The practice of bin God
This line is first divided into sections, and the information stored in each section is: the longest continuous number of 1 from the left end of the section, the number of ll, the longest continuous 1 from the right end of this section, and The maximum number of consecutive points in this section ml...
achievements : LL = RL = ml = interval length
Update :
The leaf node is placed in a zero,,,
Left and right recursive updates
Other Range: (Pushup ())
Parent node. ll = Left node. ll parent node. RL = Right node. RL
Parent node. ML takes the largest one ml of the left and right nodes
If the left node of the RL + right node ll > parent node of ML,,,,, and then update to the former
LL,RL for the parent node
If the left node ll is the length of the left node, it means that the maximum number of consecutive 1 of the left node starting from the left endpoint is the number of points that the left node contains, so the parent node will be merged with the ll of the right node at this time.
In the same vein, the parent's RL has to make such judgments.
Enquiry :
For some special intervals, the maximum number of consecutive 1 for which the interval is returned is ML
When Loc is left in the midpoint, it is judged by the left node, and the condition is whether Loc is beyond the leftmost of RL (drawing is easier to understand), and, beyond that, the continuous 11 parts of the Loc are located in the left node of RL, and the other part is in the ll of the right node, is divided into two point queries,, one is the LOC on the left node, and the other at the right node of the mid+1 that point
Similarly, if there is a similar judgment at the right of the midpoint,
In general, it is the constant judgment to find the point relative to the position of the LL,RL,, and finally the recursive query to the results of the merger on the line,,,
Word ugly forgive me,,,, (but should nobody look at it,,,,
Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring>using namespace std; const int MAXN = 5e5 + 10;struct node{int l; int R; int ml; int ll; int RL;} NODE[MAXN << 2];void Build (int rt, int l, int r) {node[rt].l = l; NODE[RT].R = R; node[rt].ml = Node[rt].ll = NODE[RT].RL = r-l + 1; At first it must be the length of the interval if (L = = r) return; int mid = (L + r) >> 1; Build (RT << 1, L, mid); Build (rt << 1 | 1, mid + 1, R); return;} void update (int rt, int loc, int val) {if (node[rt].l = = NODE[RT].R) {if (val) node[rt].ml = Node[rt].ll = n ODE[RT].RL = 1; Destroy and rebuild the two else node[rt].ml = Node[rt].ll = NODE[RT].RL = 0; Return } int mid = (node[rt].l + node[rt].r) >> 1; if (Loc <= mid) update (RT << 1, loc, Val); ELSE update (RT << 1 | 1, loc, Val); Recursive update//First update of parent node two, ll,rl node[rt].ll = Node[rt << 1].ll; Node[rt].RL = node[rt << 1 | 1].rl; Then the ml NODE[RT].ML = max (Node[rt << 1].ml, node[rt << 1 | 1].ml) of the parent node; NODE[RT].ML = Max (node[rt].ml, node[rt << 1].rl + node[rt << 1 | 1].ll); The ll,rl of the parent node may be the ll,,rl of the left and right nodes,,,, add a part of the other interval if it is exactly the child node if (node[rt << 1].ll = node[rt << 1].r-node[rt < ;< 1].L + 1) node[rt].ll + = Node[rt << 1 | 1].ll; if (node[rt << 1 | 1].rl = = NODE[RT << 1 | 1].r-node[rt << 1 | 1].l + 1) node[rt].rl + = Node[rt << 1].rl; return;} int query (int rt, int loc) {//special case directly returns ml if (node[rt].l = = NODE[RT].R | | node[rt].ml = = 0 | | node[rt].ml = = NODE[RT] . R-NODE[RT].L + 1) return node[rt].ml; int mid = (node[rt].l + node[rt].r) >> 1; if (Loc <= mid) {if (loc >= node[rt << 1].r-node[rt << 1].rl + 1) return query (RT << 1, loc) + query (rt << 1 | 1, mid + 1); else return query (RT ≪< 1, loc); } else {if (loc <= node[rt << 1 | 1].l + node[rt << 1 | 1].ll-1) return query (RT << 1 | 1, loc) + query (RT << 1, mid); Return query (RT << 1 | 1, loc); }}int Main () {int n, m; while (scanf ("%d%d", &n, &m)! = EOF) {build (1, 1, N); int Q[MAXN]; int TOC = 0; int t = 0; while (m--) {char c;scanf ("%c", &c); if (c = = ' D ') {scanf ("%d", &t); Q[toc++] = t; Save the Destroy Operation Update (1, t, 0); } else if (c = = ' Q ') {scanf ("%d", &t); printf ("%d\n", query (1, t)); } else {if (t) {t = Q[--toc]; Update (1, T, 1); }}}} return 0;} Kaungbin
hdu-1540 line segment Tree Brush title