Count-find and print on the screen the length of the longest non-decreasing subsequence of stringS.Subsequence of a stringSIs a string that can be obtained fromSBy removing zero or more of its elements. A string is called non-decreasing if each successive digit is not less than the previous one.
Help Petya process the requests.
InputThe first line contains two integersNAndM(1? ≤?N? ≤? 106 ,? 1? ≤?M? ≤? 3. 105)-the length of the stringSAnd the number of queries correspondingly. The second line containsNLucky digits without spaces-Petya's initial string. NextMLines contain queries in the form described in the statement.
OutputFor each query count print an answer on a single line.
Sample test (s) input2 347countswitch 1 2count
Output21
The data volume is large, and the query speed can be greatly improved by using the line segment tree.The key difficulty of this question is the dynamic update of the Line Segment tree. You need to set a Lazy flag, that is, you do not need to update all vertices each time, but wait until the next time you need to query this vertex, update the two child nodes at this point.
For the logical relationship, study the code carefully. The logic is still very difficult.
The line segment tree has two points:
1. Binary Tree
2 Lazy flag Dynamic Update Interval
# Include
# Include
# Include
# Include
Using namespace std; class LuckyQueries {int n, tSize; char * str; struct Node {int L4, L7, L47, L74; bool lazy ;}; Node * segTree; void updateNode (int id, int left, int right) {segTree [id]. l4 = segTree [left]. l4 + segTree [right]. l4; segTree [id]. l7 = segTree [left]. l7 + segTree [right]. l7; int a = segTree [left]. l47 + segTree [right]. l7; int B = segTree [left]. l4 + segTree [right]. l47; segTree [id]. l47 = max (a, B); a = seg Tree [left]. l74 + segTree [right]. l4; B = segTree [left]. l7 + segTree [right]. l74; segTree [id]. l74 = max (a, B); segTree [id]. lazy = false;} void conHelper (int low, int up, int id = 0) {if (low = up) {if (str [low] = '4 ') {segTree [id]. l4 = 1, segTree [id]. l7 = 0; segTree [id]. l47 = 1, segTree [id]. l74 = 0;} else {segTree [id]. l4 = 0, segTree [id]. l7 = 1; segTree [id]. l47 = 0, segTree [id]. l74 = 1;} segTree [id]. lazy = fa Lse; return;} int mid = low + (up-low)> 1); int left = id * 2 + 1; int right = id * 2 + 2; conHelper (low, mid, left); conHelper (mid + 1, up, right); updateNode (id, left, right);} void conTree () {int h = (int) ceil (double) log (double (n)/log (2.0) + 1; tSize = (int) pow (2.0, double (h)-1; segTree = (Node *) malloc (sizeof (Node) * tSize); conHelper (0, n-1);} inline int getLongestIncease () {return max (segTree [0]. l4, max (SegTree [0]. L47, segTree [0]. L7);} void invert (int root) {segTree [root]. lazy =! SegTree [root]. lazy; swap (segTree [root]. l4, segTree [root]. l7); swap (segTree [root]. l47, segTree [root]. l74);} void updateTree (const int low, const int up, int tLow, int tUp, int root = 0) {if (tUp <low | up <tLow) // error | to & {return;} if (low <= tLow & tUp <= up) {invert (root); return ;} int tMid = tLow + (tUp-tLow)> 1); int left = root * 2 + 1; int right = root * 2 + 2; if (segTree [root]. lazy) {segTree [root]. Lazy = false; invert (left); invert (right);} updateTree (low, up, tLow, tMid, left); updateTree (low, up, tMid + 1, tUp, right); updateNode (root, left, right);} public: LuckyQueries () {int m; scanf ("% d", & n, & m ); getchar (); // do not forget to remove a linefeed str = (char *) malloc (sizeof (char) * (n + 1); gets (str ); conTree (); char command [8]; for (int I = 0; I <m; I ++) {char c = getchar (); if ('c' = c) {printf ("% d \ n", getLongestIncease ()); Gets (command); // gets row} else {while (c! = '') C = getchar (); int low, up; scanf (" % d ", & low, & up); updateTree (low-1, up-1, 0, n-1); if (I + 1! = M) getchar ();}}}~ LuckyQueries () {if (str) free (str); if (segTree) free (segTree );}};