线段树求最长上升子序列
#include <iostream>
#include <cstdio>
using namespace std;
int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return f*x;
}
const int N=1e5+5;
int n,a,tre[N*4],v,m=1e5;
void modify(int k,int l,int r,int x,int v)
{
if(x>r||x<l) return;
if(l==r&&l==x)
{
tre[k]=v;
return;
}
int mid=(l+r)/2;
modify(k*2,l,mid,x,v);
modify(k*2+1,mid+1,r,x,v);
tre[k]=max(tre[k*2],tre[k*2+1]);
}
int query(int k,int l,int r,int x,int y)
{
if(r<x||l>y) return 0;
if(l>=x&&r<=y) return tre[k];
int mid=(l+r)/2;
return max(query(k*2,l,mid,x,y),query(k*2+1,mid+1,r,x,y));
}
int main()
{
freopen("sort.in","r",stdin);
freopen("sort.out","w",stdout);
n=read();
for(int i=1;i<=n;i++)
{
a=read();
v=query(1,0,m,0,a)+1;
modify(1,0,m,a,v);
}
cout<<query(1,0,m,0,m);
fclose(stdin); fclose(stdout);
return 0;
}