最长不上升子序列+最长上升子序列
#include <iostream>
#include <cstdio>
using namespace std;
const int N=1e5+5,M=5e5+5;
int tre[M*4],a[N],n,m=5e5+5,a1,v;
void del(int k,int l,int r)
{
tre[k]=0;
if(l==r) return;
int mid=(l+r)/2;
del(k*2,l,mid);
del(k*2+1,mid+1,r);
}
void change(int k,int l,int r,int x,int v)
{
if(l>x||r<x) return;
if(l==r)
{
tre[k]=v;
return;
}
int mid=(l+r)/2;
change(k*2,l,mid,x,v);
change(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(l>y||r<x) 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()
{
while(scanf("%d",&a1)==1) a[++n]=a1;
for(int i=1;i<=n;i++)
{
v=query(1,1,m,a[i],m)+1;
change(1,1,m,a[i],v);
}
cout<<query(1,1,m,1,m)<<"\n";
del(1,1,m);
for(int i=1;i<=n;i++)
{
v=query(1,1,m,1,a[i]-1)+1;
change(1,1,m,a[i],v);
}
cout<<query(1,1,m,1,m);
return 0;
}