• [CF486E] LIS of Sequence


    Description

    给定一个数列,对于每个元素,问它属于以下哪一类:必须在最长上升子序列中;可能在最长上升子序列中,不可能在最长上升子序列中。

    Solution

    求每个元素开头和结尾的最长上升子序列长度 (f[i])(g[i])

    如果 (f[i]+g[i]-1<ans),其中 (ans) 是整个序列的最长上升子序列,则 (i) 不可能在最长上升子序列中

    如果存在 (j),使得 (f[i]=f[j], g[i]=g[j]),则 (i) 不在所有的最长上升子序列中

    否则,(i) 一定在所有的最长上升子序列中

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    namespace lis
    {
    int n,a[N],f[N],g[N];
    void solve()
    {
        for(int i=0;i<=n;i++) g[i]=1e18;
        for(int i=1;i<=n;i++)
        {
            int pos=lower_bound(g+1,g+n+1,a[i])-g;
            g[pos]=a[i];
            f[i]=pos;
        }
    }
    }
    
    int n,a[N],f[N],g[N];
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        lis::n=n;
        for(int i=1;i<=n;i++)
        {
            lis::a[i]=a[i];
        }
        lis::solve();
        for(int i=1;i<=n;i++)
        {
            f[i]=lis::f[i];
        }
        for(int i=1;i<=n;i++)
        {
            lis::a[i]=-a[n-i+1];
        }
        lis::solve();
        for(int i=1;i<=n;i++)
        {
            g[i]=lis::f[n-i+1];
        }
        int ans=*max_element(f+1,f+n+1);
        map<int,int> s;
        for(int i=1;i<=n;i++)
        {
            s[f[i]*1000000+g[i]]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(f[i]+g[i]-1<ans) cout<<1;
            else if(s[f[i]*1000000+g[i]]>1) cout<<2;
            else cout<<3;
        }
    }
    
    
  • 相关阅读:
    深入理解PHP原理之变量作用域
    深入理解PHP原理之变量分离/引用
    关于哈希表
    foreach 相关
    Scrapyd-Client的安装
    Scrapyd API的安装
    scrapyd的安装
    快手的小视频爬取
    实现单例模式的几种方式
    京东图书分布式爬虫
  • 原文地址:https://www.cnblogs.com/mollnn/p/13605706.html
Copyright © 2020-2023  润新知