LIS与LCS的nlogn解法

LIS(nlogn)

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e5+5;
int a[maxn];
int n;
int lis[maxn];
int len=1;
int find(int x){
    int l=1,r=len,m;
    while(l<r){
        m=l+(r-l)/2;
        if(lis[m]>=a[x]){//这里若去掉等号即为 非严格递增序列 
            r=m;
        } 
        else{
            l=m+1;
        }
    }
    return l;
}
int main(void){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    lis[1]=a[1];
    for(int i=2;i<=n;i++){
        if(a[i]>lis[len]){
            lis[++len]=a[i];
        }
        else{
            int pos=find(i);
            lis[pos]=a[i];
        }
    }
    printf("%d",len);
    return 0;
}

LCS(nlogn)

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=1e6+5;
int n,len=0;
int lis[maxn];
int a[maxn];
int b[maxn];
int loc[maxn];
int find(int x){
    int l=1,r=len,m;
    while(l<r){
        m=l+(r-l)/2;
        //if(lis[m]>=b[x]){//智障错误,找了那么久。。 
        if(lis[m]>=x){
            r=m;
        }
        else  l=m+1;
    }
    return l;
}
int main(void){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++){
        scanf("%d",&b[i]);
        loc[b[i]]=i;
    }
    for(int i=1;i<=n;i++){
        b[i]=loc[a[i]];
    }
//    for(int i=1;i<=n;i++)printf("%d",b[i]) ;// 
//    printf("
");
    if(n!=0)lis[++len]=b[1];
    for(int i=2;i<=n;i++){
        if(b[i]>lis[len]){
            lis[++len]=b[i];
        }
        else{
            int pos=find(b[i]);
            lis[pos]=b[i];
        }
    }
    printf("%d",len);
    return 0;
}
原文地址:https://www.cnblogs.com/yzm10/p/9502347.html