lower_bound(a,a+n,k) 二分求ai>=k的ai的最小的指针。
upper_bound(a,a+n,k) 二分求ai>k的ai的最小的指针。
例:可以求长度为n的有序数组a中的k的个数,即为upper_bound(a,a+n,k)-lower_bound(a,a+n,k)。
fill(a,a+n,x);
将数组a0~an位置赋值为x。
下面为nlogn时间内求LIS。
#include<iostream>
#include<stdio.h>
#include<math.h>
#include <string>
#include<string.h>
#include<map>
#include<set>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define pi 3.1415926535898
#define eps 1e-8
#define inf 0x3f3f3f3f
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define ll long long int
#define maxn 100005
int dp[maxn];
int a[maxn];
int n;
void solve(){//求最长上升子序列(LIS)(nlogn)
fill(dp,dp+n,inf);//fill函数是用来把0~n的位置赋值为某个值
for(int i=0;i<n;i++)
{
*lower_bound(dp,dp+n,a[i])=a[i];
//如果子序列的长度相同,那么最末位的元素较小的在之后的会更加有优势,
//所以我们反过来用dp针对长度相同的情况下最小的末尾元素进行求解。
}
printf("%d\n",lower_bound(dp,dp+n,inf)-dp);
}
int main()
{
rd(n);
for(int i=0;i<n;i++)
{
rd(a[i]);
}
solve();
return 0;
}