//时间复杂度:O(nlogn)
#include<set>
#include<stack>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int Min(int *a, int len){
int min = 0;
for (int i = 0; i < len; i++)
if (a[i] < min)
min = a[i];
}
int LIS(int *a, int len){
//存储对应递增序列长度的最大值的最小元素
int *MaxV = new int[len + 1];
MaxV[1] = a[0];//数组中的第一值,边界值
MaxV[0] = Min(a, len) - 1;//数组中的最小边界值
//存储对应索引的序列长度
int *LISAry = new int[len];
for (int i = 0; i < len; i++)
LISAry[i] = 1;
int nMaxILS = 1;//数组最长递增序列的长度
for (int i = 1; i < len; i++){
if (a[i] > MaxV[nMaxILS]){
nMaxILS++;
MaxV[nMaxILS] = a[i];
LISAry[i] = nMaxILS;
}
else{
int low = 1, height = nMaxILS;
//利用二分法寻找从前向后第一个大于a[i]元素的索引
while (low <= height){
int mid = low + (height - low) / 2;
if (a[i] >= MaxV[mid]){
low = mid + 1;
}
else{
height = mid - 1;
}
}
LISAry[i] = low;
//更新递增序列长度为low其最大元素改为更小的a[i]
MaxV[low] = a[i];
}
}
return nMaxILS;
}
int main(){
int a[8] = { 1,-1,2,-3,4,-5,6,-7 };
int len = sizeof(a) / sizeof(int);
cout << LIS(a, len) << endl;
return 0;
}