1. 程式人生 > >線段樹解LIS

線段樹解LIS

先是nlogn的LIS解法

/*
LIS nlogn解法 
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
//結尾的數字越小,說明相同長度下當前序列越優 
int lis[100005],a[100005];//lis[i]表示長度為i的最優的結尾數 
int n,len=0;
int find(int x){//找到lis中第一個大於等於x的數的下標 
    int l=0,r=len; 
    while(l<r){
        int mid=l+r>>1
; if(lis[mid]>=x) r=mid; else l=mid+1; } return l; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); lis[1]=a[1];len++; for(int i=2;i<=n;i++){//按順序處理每一個數 if(a[i]>lis[len])//可以更新新長度了 lis[++len]=a[i];
else{//對於一個a[i],可以更新以它為結尾的最長lis的結尾 int pos=find(a[i]);//找到lis中第一個大於等於a[i]的數,pos也是以那個數結尾的長度 lis[pos]=a[i]; //把那個數替換了 } } printf("%d\n",len); return 0; }

線段樹解LIS