zoukankan      html  css  js  c++  java
  • 树状数组优化最长上升子序列

    最长上升子序列比较暴力的写法是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;
    }
  • 相关阅读:
    十进制,二进制,八进制,十六进制中的相互转换
    oracle中dual表的使用
    弹出窗口
    oracle中的函数
    [导入]几种所见所得的在线编辑器
    操作字符串
    设计模式初认识
    创建型模式之简单工厂模式
    MySQL批量检查表的脚本
    中英文单位对照
  • 原文地址:https://www.cnblogs.com/WHFF521/p/11730074.html
Copyright © 2011-2022 走看看