CF568E. Longest Increasing Subsequence
阿新 • • 發佈:2020-09-12
題目大意
題解
從各種意義上來說都很離譜的題
看到k<=1e3,一眼k^2logn,結果是(n+m)k,1.5s兩億
並且還是上升子序列,所以用nlogn的方法在不確定時維護指標掃一遍轉移即可
關於如果是單調不減的思考(口胡):
在維護的時候維護填入的相同數個數,轉移時考慮還要加上個數的限制,陣列中一段相同數的出現次數應該是前面一段0,之後一段單調+1序列,所以二分之後暴力修改至多k次
code
#include <bits/stdc++.h> #define fo(a,b,c) for (a=b; a<=c; a++) #define fd(a,b,c) for (a=b; a>=c; a--) #define ll long long //#define file using namespace std; int a[100001],b[100001],c[100001],d[100001],f[100001],id[100001],pre[100001],n,m,i,j,k,l,r,mid,tot; int main() { #ifdef file freopen("CF568E.in","r",stdin); #endif scanf("%d",&n); fo(i,1,n) scanf("%d",&a[i]); scanf("%d",&m); fo(i,1,m) scanf("%d",&b[i]); sort(b+1,b+m+1); if (a[1]>-1) tot=1,f[1]=a[1],id[1]=1,pre[1]=0; else tot=1,f[1]=b[1],id[1]=0,pre[1]=0; fo(i,2,n) if (a[i]>-1) { l=1;r=tot; while (l<r) { mid=(l+r)/2; if (f[mid]<a[i]) l=mid+1; else r=mid; } if (a[i]>f[tot]) f[++tot]=a[i],id[tot]=i,pre[i]=id[tot-1]; else f[l]=a[i],id[l]=i,pre[i]=id[l-1]; } else { if (b[m]>f[tot]) f[++tot]=b[m],id[tot]=id[tot-1]; k=tot; fd(j,m,1) { while (k>1 && f[k-1]>=b[j]) --k; if (b[j]<f[k]) f[k]=b[j],id[k]=id[k-1]; } } for (i=id[tot]; i; i=pre[i]) c[i]=d[i]=a[i]; if (!c[n]) c[n]=1000000001; fd(i,n-1,1) c[i]=(c[i]>0)?c[i]:c[i+1]; fo(i,2,n) d[i]=(d[i]>0)?d[i]:d[i-1]; j=1; fo(i,1,n) if (a[i]==-1) { while (j<=m && b[j]<=d[i]) ++j; if (j<=m && b[j]<c[i]) { while (j<m && b[j]==b[j+1]) ++j; a[i]=b[j],b[j]=-1,++j; } } j=1; fo(i,1,n) if (a[i]==-1) { while (j<=m & b[j]==-1) ++j; a[i]=b[j],++j; } fo(i,1,n) printf("%d ",a[i]); printf("\n"); fclose(stdin); fclose(stdout); return 0; }