zoukankan      html  css  js  c++  java
  • CF568E Longest Increasing Subsequence

    先留个坑,输出方案的地方还得再想想

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 100010;
    const int INF = 1e9+7;
    
    int n,m,len,cnt;
    int a[maxn],b[maxn],c[maxn];
    int pre[maxn],from[maxn],tmp[maxn],v[maxn];
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        m=read();
        for(int i=1;i<=m;i++) b[i]=read();
        sort(b+1,b+1+m);
    //    for(int i=1;i<=n;i++) c[i]=INF;
        
        len=0;
        for(int i=1;i<=n;i++){
            if(~a[i]){
                int p=lower_bound(c+1,c+1+len,a[i])-c;
                pre[i]=from[p-1];
                from[p]=i;
                c[p]=a[i];
                if(len<p) len=p;
                
            }else{
                int k=1;
                for(int j=1;j<=m;++j){
                    while(k<=len&&c[k]<b[j]) ++k;
                    tmp[j]=k;
                }
                if(len<k) len=k;
                for(int j=m;j;j--){
                    c[tmp[j]]=b[j];
                    from[tmp[j]]=from[tmp[j]-1];
                }
            }
        }
        cnt=0;
        for(int i=from[len];i;i=pre[i]){
            tmp[++cnt]=i;
        }
        tmp[0]=n+1;
        tmp[cnt+1]=0;
        
        a[n+1]=INF; b[m+1]=INF;
        for(int i=cnt+1;i;i--){ // 找到b中填到lis位置上的数 
            int last=a[tmp[i]];
            for(int j=tmp[i]+1;j<tmp[i-1];j++){
                if(!~a[j]){
                    int k=upper_bound(b+1,b+1+m,last)-b;
                    if(k>m||b[k]>=a[tmp[i-1]]) break;
                    v[k]=1;
                    last=a[j]=b[k];
                }
            }
        }
        
        for(int i=1,j=1;i<=n;i++){
            if(!~a[i]){
                while(j<m&&v[j]) ++j;
                a[i]=b[j];
                v[j]=1;
            }
        }
        for(int i=1;i<=n;i++){
            printf("%d ",a[i]);
        }printf("\n");
        
        return 0;
    }
  • 相关阅读:
    js 生成指定范围之内的随机数
    vue项目在ie浏览器打开做提示
    vue 瀑布流组件
    docker 移动文件到其他目录
    学习hyperf遇到的问题
    Linux 部署elasticsearch
    Git 常用命令
    Linux svn定时更新
    eclipse 导入web项目后,线程假死
    向量基本概念
  • 原文地址:https://www.cnblogs.com/tuchen/p/10421237.html
Copyright © 2011-2022 走看看