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