树状数组优化最长上升子序列

Posted whff521

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树状数组优化最长上升子序列相关的知识,希望对你有一定的参考价值。

最长上升子序列比较暴力的写法是n的,实际上我们求得就是前面的比当前小的最长上升子序列的最大值;

树状数组可以优化它;

倒过来求就是最长下降子序列;

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

 

以上是关于树状数组优化最长上升子序列的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3173 最长上升子序列 树状数组

树状数组求LIS(最长上升子序列)

严格上升子序列数(树状数组)(离散化优化)

BZOJ3173: [Tjoi2013]最长上升子序列(树状数组)

用树状数组写的最长上升子序列(友好城市),nlogn。

bzoj5157: [Tjoi2014]上升子序列(树状数组LIS)