"cf486e" LIS of sequence problem link test instructions:
Give you a sequence of n-length a1,a2,..., An, you need to divide the n elements into three categories:
1: All the longest ascending sub-sequences do not contain this element
2: Has but not all of the longest ascending subsequence contains this element
3: All the longest ascending sub-sequences contain this element
Input format:
The first line contains a positive integer n, which represents the length of the sequence. The second row contains n positive integers a1,a2,..., An, which represents the elements in the sequence.
Output format:
A row that contains a string of length n, consisting of three numbers of three-in-one, and the first number indicates the category of AI.
Sample Input 1:
1 4
Sample Output 1:
3
Sample Input 2:
4 1 3 2 5
Sample Output 2:
3223
Sample Input 3:
4 1 5 2 3
Sample Output 3:
3133
Space-Time Limitations:
Each test point 2S,256MB
Data range:
1≤n≤105
1≤ai≤105
Exercises
First of all, O (NLOGN) to ask the LIS everyone should be ... There is no elaboration here.
We can calculate the length of the longest ascending subsequence at the end of each point by DP, which is recorded as Length[i], and record the LIS length of the whole sequence as Len.
Then, you need to understand a proposition:
If the element I may appear in the LIS, then its position in the LIS must be exactly equal to length[i].
This self-proof is not difficult.
Secondly, we can use a "layered array", in fact, the so-called "layered array" is a two-dimensional array, but I am accustomed to the first dimension is called "Layer", the second dimension because space saving, we open a vector.
This "layered array" is very important and it is the core of our problem solving. We have calculated the length[i of each element in DP, so we add the number of this element to the vector of length[i], so each point in the layered array corresponds to element one by one in the sequence.
This is the process of establishing a "layered array", which can be found in code comments.
And then what?
We also need to understand two propositions:
In each layer, as the number increments, the value of the element corresponding to the point is monotonically not incremented.
Each point in each layer (except the first layer) must have a node in the previous layer that has a number less than it and the sequence element value is less than it.
Consider our DP process, when we update the minimum value of Length[i] in the DP array, if the element's length[i is already calculated by a binary search [], the element can be updated Dp[length[i]] The condition is that the value of the element must not be greater than dp[length[i]] , Dp[length[i]] has been calculated from the previous element, so in a layer with a "layered array" layer of length[i], the value of the element must be less than or equal to the value of the element that is smaller than it in that layer.
In addition, when we are DP, we can understand that the value of the dp[length[i]-1] is smaller than that of the a[i] in terms of the monotonically increasing characteristics of the DP array, so in the previous layer of the "layered array" there must be a point with a number less than it and the sequence element value less than it, so as to ensure that we do not appear " A pair of empty "cases, but in the previous layer there is an interval (containing the number, sequence element value two) corresponding to it. The point in this interval is the node that the current point can be extended to in the previous layer.
You may have questions: why push backwards from behind?
Because backward push can guarantee to expand the current point must have lis through it, so it extends to the previous layer of the node also must have Lis pass, until the layer is a little expanded, the previous layer has not been extended to the point must not have the LIS, hit the "1" class tag, the next extension do not expand these points. While the other points are labeled "2", if there is only one "2" class tag, then the "2" is changed to "3", indicating that the node is the necessary node for all LIS.
The reference code is as follows (if you do not understand the comments):
1#include <cstdio>2#include <cstring>3#include <algorithm>4#include <vector>5 #defineMAXN 1000056 using namespacestd;7 intN,A[MAXN];//entire sequence8 intDP[MAXN];//Dp[i] Represents the minimum value of the element at the end of the ascending subsequence of the current length of I9 intlen=0;//The length of the entire sequence LisTen intSIGN[MAXN];//The category to which the sequence element belongs Onevector<int>layer[maxn];//layered Array, there is a Len layer altogether. The points in Layer[i] represent these elements: the longest ascending subsequence length ending with these elements is I AInlineintBinsintIintval) { - intL=0, R=layer[i].size ()-1; - while(l<R) { the intM= (l+r) >>1; - if(A[layer[i][m]]>=val) l=m+1; - ElseR=m; - } + returnl; - } + intMain () { Ascanf"%d",&n); atMemset (DP,0x3f,sizeof(DP)); -dp[0]=0; - for(intI=1; i<=n;i++){ -scanf"%d",&a[i]); - intLength=lower_bound (dp,dp+n+1, A[i])-DP;//O (NLOGN) Seek Lis -dp[length]=min (dp[length],a[i]); in //length indicates the longest ascending subsequence of the end of the element -Layer[length].push_back (i);//adding to a layered array toLen=max (len,length);//Update the LIS length for the entire sequence + } - for(intI=1; i<=n;i++) sign[i]=1;//initialization is all class 1th, that is, any LIS does not pass through them the if(layer[len].size () = =1) sign[layer[len][0]]=3; * Else for(intI=0; I<layer[len].size (); i++) sign[layer[len][i]]=2; $ for(inti=len;i>=2; i--) {//reverse-process layered arrays, one layer at a-a-level push forwardPanax Notoginseng for(intj=0; J<layer[i].size (); j + +) {//Enumerate all points of the current layer - intBH=LAYER[I][J];//Number of points the if(sign[bh]>1){//if the current node can be extended forward (existing LIS passes the current point) + intL=bins (I-1, A[BH]);//binary Lookup, the extended node must be less than the current node in the sequence to ensure that the LIS is strictly incremented A intR=lower_bound (layer[i-1].begin (), layer[i-1].end (), BH)-layer[i-1].begin ()-1;//binary Lookup, the expanded point number must be less than the current point number in order to be a "sequence" the //The range of points at the previous level to which the current point can be extended is the interval [l,r] + for(intk=l;k<=r;k++) sign[layer[i-1][k]]=2;//marked, the node can be extended to indicate that there must be an LIS in the entire sequence that contains that point - } $ } $ //The point at the front level that the current layer can extend to is the set of nodes at the previous level that the current layer can extend somewhat . - intCnt=0, pos=0; - for(intj=0; j<layer[i-1].size (); j + +)if(sign[layer[i-1][j]]==2){ thecnt++; -pos=J;Wuyi } the if(cnt==1) sign[layer[i-1][pos]]=3;//if all the extensible points of the layer can only extend one node in the previous layer, this node is the required node for all LIS. - } Wu for(intI=1; i<=n;i++) printf ("%d", Sign[i]);//Print without spaces - return 0; About}
"cf486e" LIS of sequence