LCIS
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission (s): 1713 Accepted Submission (s): 748
Problem DescriptionGiven n integers.
You have two operations:
U a B: replace the Ath number by B. (index counting from 0)
Q a B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, B].
InputT in the first line, indicating the case number.
Each case starts with two integers n, m (0 <n, m <= 105 ).
The next line has n integers (0 <= val <= 105 ).
The next m lines each has an operation:
U a B (0 <= A, n, 0 <= B = 105)
OR
Q a B (0 <= A <= B <n ).
OutputFor each Q, output the answer.
Sample Input
110 107 7 3 3 5 9 9 8 1 8 Q 6 6U 3 4Q 0 1Q 0 5Q 4 7Q 3 5Q 0 2Q 4 6U 6 10Q 0 9
Sample Output
11423125
Authorsh
SourceHDOJ Monthly Contest-2010.02.06
The Recommendwxl question can reflect the versatility of the Line Segment tree. The information saved by the interval node greatly optimizes the time to be seen from a lot of information saved in the node, the key to the line segment tree question is what information is stored and how to use the information needs to be carefully considered tree [n]. num, tree [n]. tagl, tree [n]. tagr, how to update these values may be amazing 1Y. Unfortunately, I wrote something wrong and didn't realize this pleasure...
# Include <stdio. h ># include <algorithm> using namespace std; struct Node {int l, r, num; int first, end; int tagl, tagr;} tree [1000000]; void Build (int n, int x, int y) {tree [n]. l = x; tree [n]. r = y; int mid = (x + y)/2; if (x = y) {int a; scanf ("% d", & ); tree [n]. first = a; // value tree of the first element of the interval [n]. end = a; // The end element of the interval .. Tree [n]. num = 1; // The longest sequence tree in the interval [n]. tagl = 1; // The longest ascending sequence tree from left [n]. tagr = 1; // start from the right ...... Return;} Build (2 * n, x, mid); Build (2 * n + 1, mid + 1, y); tree [n]. first = tree [2 * n]. first; tree [n]. end = tree [2 * n + 1]. end; // if the entire left son interval is continuous, and the last element <the first element of the right son interval if (tree [2 * n]. num = (tree [2 * n]. r-tree [2 * n]. l + 1) & tree [2 * n]. end <tree [2 * n + 1]. first) tree [n]. tagl = tree [2 * n]. num + tree [2 * n + 1]. tagl; else tree [n]. tagl = tree [2 * n]. tagl; // tagr is the same as if (tree [2 * n + 1]. num = (tree [2 * n + 1]. r-tree [2 * n + 1]. l + 1) & tree [2 * n]. end <tree [2 * n + 1]. first) tree [n]. tagr = tree [2 * n + 1]. num + tree [2 * n]. tagr; else tree [n]. tagr = tree [2 * n + 1]. tagr; // tree [n]. num if (tree [2 * n]. end <tree [2 * n + 1]. first) tree [n]. num = max (tree [2 * n]. tagr + tree [2 * n + 1]. tagl, max (tree [2 * n]. num, tree [2 * n + 1]. num); else tree [n]. num = max (tree [2 * n]. num, tree [2 * n + 1]. num);} void Modify (int n, int x, int y) {int l = tree [n]. l; int r = tree [n]. r; int mid = (l + r)/2; if (l = r) {tree [n]. first = y; tree [n]. end = y; return;} if (x <= mid) Modify (2 * n, x, y); else Modify (2 * n + 1, x, y ); // update all values in the node. tree [n] is the same as that in Build. first = tree [2 * n]. first; tree [n]. end = tree [2 * n + 1]. end; if (tree [2 * n]. num = (tree [2 * n]. r-tree [2 * n]. l + 1) & tree [2 * n]. end <tree [2 * n + 1]. first) tree [n]. tagl = tree [2 * n]. num + tree [2 * n + 1]. tagl; else tree [n]. tagl = tree [2 * n]. tagl; if (tree [2 * n + 1]. num = (tree [2 * n + 1]. r-tree [2 * n + 1]. l + 1) & tree [2 * n]. end <tree [2 * n + 1]. first) tree [n]. tagr = tree [2 * n + 1]. num + tree [2 * n]. tagr; else tree [n]. tagr = tree [2 * n + 1]. tagr; if (tree [2 * n]. end <tree [2 * n + 1]. first) tree [n]. num = max (tree [2 * n]. tagr + tree [2 * n + 1]. tagl, max (tree [2 * n]. num, tree [2 * n + 1]. num); else tree [n]. num = max (tree [2 * n]. num, tree [2 * n + 1]. num);} int Searchl (int n, int x, int y) {int l = tree [n]. l; int r = tree [n]. r; int mid = (l + r)/2; if (l = x & r = y) {return tree [n]. tagl;} if (x <= mid & y <= mid) return Searchl (2 * n, x, y); else if (x> mid & y> mid) return Searchl (2 * n + 1, x, y); else if (Searchl (2 * n, x, mid) = (mid-x + 1) & tree [2 * n]. end <tree [2 * n + 1]. first) return (mid-x + 1) + Searchl (2 * n + 1, mid + 1, y); else return Searchl (2 * n, x, mid );} int Searchr (int n, int x, int y) {int l = tree [n]. l; int r = tree [n]. r; int mid = (l + r)/2; if (l = x & r = y) {return tree [n]. tagr;} if (x <= mid & y <= mid) return Searchr (2 * n, x, y); else if (x> mid & y> mid) return Searchr (2 * n + 1, x, y); else if (Searchr (2 * n + 1, mid + 1, y) = (y-(mid + 1) + 1) & tree [2 * n]. end <tree [2 * n + 1]. first) return Searchr (2 * n, x, mid) + (y-mid); else return Searchr (2 * n + 1, mid + 1, y );} int Find (int n, int x, int y) {int l = tree [n]. l; int r = tree [n]. r; int mid = (l + r)/2; if (l = x & r = y) {return tree [n]. num;} int ans; if (x <= mid & y <= mid) ans = Find (2 * n, x, min (y, mid )); else if (y> mid & x> mid) ans = Find (2 * n + 1, max (x, mid + 1), y ); else if (tree [2 * n]. end <tree [2 * n + 1]. first) ans = max (Searchr (2 * n, x, mid) + Searchl (2 * n + 1, mid + 1, y), max (Find (2 * n, x, min (y, mid), Find (2 * n + 1, max (x, mid + 1), y ))); else ans = max (Find (2 * n, x, min (y, mid), Find (2 * n + 1, max (x, mid + 1 ), y); return ans;} int main () {int t, m, n; int I; char str [10]; int a, B; scanf ("% d", & t); while (t --) {scanf ("% d", & n, & m); Build (, n-1 ); for (I = 0; I <m; I ++) {scanf ("% s % d", str, & a, & B ); // only one character is saved in time. % s is used instead of % c. if (str [0] = 'q ') printf ("% d \ n", Find (1, a, B); else Modify (1, a, B) ;}} return 0 ;}