树状数组解决LIS---O(nlogn)
树状数组解决LIS---O(nlogn)
之前写过二分查找的LIS,现在不怎么记得了,正好用Bit来搞一波。
f[i]表示以a[i]结尾的LIS的长度。
t[x]表示以数值x结尾的LIS的长度。即t[x]=max(f[j]),a[j]==x,j<i。
f[i]=max(t[x])+1,x<a[i]或x<=a[i](这取决于上升还是不下降)。
//绝大多数要要离散化后离线操作
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<cstring> #define inf 2147483647 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() //by war //2017.10.17 using namespace std; int n; int t[100000]; int ans; int f[100000]; int x; void in(int &x) { int y=1; char c=g();x=0; while(c<'0'||c>'9') { if(c=='-') y=-1; c=g(); } while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); x*=y; } void o(int x) { if(x<0) { p('-'); x=-x; } if(x>9)o(x/10); p(x%10+'0'); } int getmax(int k) { int Max=-inf; for(;k>0;k-=(-k)&k) Max=max(Max,t[k]); return Max; } void modify(int k,int Max) { for(;k<=10000;k+=(-k)&k) t[k]=max(t[k],Max); } int main() { in(n); For(i,1,n) { in(x); f[i]=getmax(x)+1; ans=max(ans,f[i]); modify(x,f[i]); } o(ans); return 0; }