求LIS(O(nlogn))及fill、lower_bound、upper_bound函数

来源:互联网 发布:手机淘宝在哪里做代理 编辑:程序博客网 时间:2024/04/28 21:12

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 100005int 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;}



0 0
原创粉丝点击