[模板] LIS 最长递增子序列 / 最长递减子序列

O(nlogn)

注意二分写法

//#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
 
const int MAXN = 1e6 + 10;

int arr[MAXN], brr[MAXN] = {0};

void put(int blen)
{
    for(int i = 0; i < blen; i++)
        cout<<brr[i]<<' ';
        
    cout<<endl;
}

int lb(int lst, int key)
{
    int fst = 0, mid;
    lst--;

    while(fst < lst)
    {
        mid = (fst + lst) / 2;
        if(brr[mid] < key)
            lst = mid;
        else 
            fst = mid + 1;
    }
    return lst;
}

int main()
{
    //ios::sync_with_stdio(false);
 
    //cin.tie(0);     cout.tie(0);
 
    int len = 0;

    while(cin>>arr[len])
    {
    	len++;
    }

    int blen = 1;

    brr[blen - 1] = arr[0];

    for(int i = 1; i < len; i++)
    {
        if(arr[i] <= brr[blen - 1])
        {
            brr[blen] = arr[i];
            blen++;
        }
        else
        {
            int pos =  lb(blen, arr[i]);
            brr[pos] = arr[i];
        }
//        cout<<arr[i]<<"     ";
//       	put(blen); 
    }
    
    cout<<blen<<endl;
    
    vector <int> lis;
    
    lis.push_back(arr[0]);
    
    for(int i = 1; i < len; i++)
    {
     if(arr[i] > lis[lis.size() - 1])
         lis.push_back(arr[i]);
     else
         lis[lower_bound(lis.begin(), lis.end(), arr[i]) - lis.begin()] = arr[i];
    }
    
    cout<<lis.size()<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/zeolim/p/12270430.html