最长上升子序列比较暴力的写法是n2 的,实际上我们求得就是前面的比当前小的最长上升子序列的最大值;
树状数组可以优化它;
倒过来求就是最长下降子序列;
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
typedef double dd;
typedef long long ll;
ll n;
ll a[maxn];
ll id[maxn];
ll f[maxn],g[maxn];
ll b1[maxn],b2[maxn];
int len;
ll query_front(int x)
{
ll ans=0;
for(;x;x-=x&(-x)) ans=max(b1[x],ans);
return ans;
}
ll query_back(int x)
{
ll ans=0;
for(;x;x-=x&(-x)) ans=max(b2[x],ans);
return ans;
}
void add_front(int x,ll y)
{
for(;x<=len;x+=x&(-x)) b1[x]=max(b1[x],y);
}
void add_back(int x,ll y)
{
for(;x<=len;x+=x&(-x)) b2[x]=max(b2[x],y);
}
dd ans;
int qw[maxn];
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
id[i]=a[i];
}
sort(id+1,id+n+1);
len=unique(id+1,id+n+1)-id-1;
for(int i=1;i<=n;i++) qw[i]=lower_bound(id+1,id+len+1,a[i])-id;
for(int i=1;i<=n;i++)
{
f[i]=query_front(qw[i]-1)+a[i];
g[n-i+1]=query_back(qw[n-i+1]-1)+a[n-i+1];
add_front(qw[i],f[i]);
add_back(qw[n-i+1],g[n-i+1]);
}
return 0;
}