Hdu1540 Tunnel Warfare (line segment tree)
Tunnel WarfareTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission (s): 6052 Accepted Submission (s): 2340
Problem Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. generally speaking, ages connected by tunnels lay in a line. cannot the two at the ends, every village was directly connected with two neighboring ones.
Frequently the invaders launched attack on some of the versions and destroyed the parts of tunnels in them. the Eighth Route Army commanders requested the latest connection state of the tunnels and ages. if some versions are severely isolated, restoration of connection must be done immediately!
Input The first line of the input contains two positive integers n and m (n, m ≤ 50,000) indicating the number of versions and events. Each of the next m lines describes an event.
There are three different events described in different format shown below:
D x: The x-th village was destroyed.
Q x: The Army commands requested the number of versions that x-th village was directly or indirectly connected with including itself.
R: The village destroyed last was rebuilt.
Output the answer to each of the Army commanders 'request in order on a separate line.
Sample Input
7 9D 3D 6D 5Q 4Q 5RQ 4RQ 4
Sample Output
1024
Source POJ Monthly
Question: D indicates the damaged tunnel, R indicates that the last damaged tunnel is repaired, and Q indicates that the query contains the longest range of x. Analysis: use three variables to record the Left Continuous interval, right continuous interval, and maximum continuous interval. If you do not know how to say this, check the code. If you still can't understand it, let's look at it here. It's quite detailed.
DetailsPs: You must be careful when writing code. I checked my eyes for the last two days because of a symbolic problem.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include using namespace std; const double eps = 1e-6; const double pi = acos (-1.0); const int INF = 0x3f3f3f; const int MOD = 1000000007; # define ll long # define CL (a, B) memset (a, B, sizeof (a) const int MAXN = 50000 + 10; struct node {int l, r; int ls, rs, ms; // ls is the left maximum continuous interval, rs is the right, ms is the maximum continuous length} t [MAXN <2]; int n, m; int s [MAXN], top; // simulate stack void build (int x, int y, int num) {t [num]. l = x; t [num]. r = y; t [num]. ls = t [num]. rs = t [num]. ms = y-x + 1; if (x = y) return; int mid = (x + y)> 1; build (x, mid, num <1); build (mid + 1, y, num <1 | 1);} void update (int x, int num, int OK) {if (t [num]. l = t [num]. r) {if (OK) // fix t [num]. ls = t [num]. rs = t [num]. ms = 1; else // destroy t [num]. ls = t [num]. rs = t [num]. ms = 0; return;} int mid = (t [num]. l + t [num]. r)> 1; if (x <= mid) update (x, num <1, OK); else update (x, num <1 | 1, OK ); t [num]. ls = t [num <1]. ls; t [num]. rs = t [num <1 | 1]. rs; t [num]. ms = max (t [num <1]. ms, t [num <1 | 1]. ms), t [num <1]. rs + t [num <1 | 1]. ls); if (t [num <1]. ls = t [num <1]. r-t [num <1]. l + 1) // If the left subtree is full, add the left interval t [num] of the right subtree to the left interval of the father. ls + = t [num <1 | 1]. ls; if (t [num <1 | 1]. rs = t [num <1 | 1]. r-t [num <1 | 1]. l + 1) // Similarly, t [num]. rs + = t [num <1]. rs;} int query (int x, int num) {if (t [num]. l = t [num]. r | t [num]. ms = 0 | t [num]. ms = t [num]. r-t [num]. l + 1) return t [num]. ms; int mid = (t [num]. l + t [num]. r)> 1; if (x <= mid) {if (x> = t [num <1]. r-t [num <1]. rs + 1) // because x <= mid, look at the left subtree, t [num <1]. r-t [num <1]. rs + 1 indicates the left boundary value of the right consecutive interval of the Left subtree. If t is in the right interval of the Left subtree, the return query (x, num <1) + query (mid + 1, num <1 | 1); else return query (x, num <1 ); // if it is not in the right boundary of the Left subtree, you only need to check the left subtree} else {if (x <= t [num <1 | 1]. l + t [num <1 | 1]. ls-1) // similarly return query (x, num <1 | 1) + query (mid, num <1); else return query (x, num <1 | 1) ;}} int main () {char ch [2]; // actually, I don't know why I can't use a single character, will RE int x; while (scanf ("% d", & n, & m) = 2) {top = 0; build (1, n, 1 ); while (m --) {// getchar (); scanf ("% s", ch); if (ch [0] = 'D ') {scanf ("% d", & x); s [top ++] = x; update (x, 1, 0 );} else if (ch [0] = 'q') {scanf ("% d", & x); printf ("% d \ n", query (x, 1) ;}else {if (top> 0) {x = s [-- top]; update (x, 1, 1) ;}}} return 0 ;}