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