题目大意
题解
从各种意义上来说都很离谱的题
看到k<=1e3,一眼k^2logn,结果是(n+m)k,1.5s两亿
并且还是上升子序列,所以用nlogn的方法在不确定时维护指针扫一遍转移即可
转移的时候记下来上一个非-1的位置,最后贪心填
关于如果是单调不减的思考(口胡):
在维护的时候维护填入的相同数个数,转移时考虑还要加上个数的限制,数组中一段相同数的出现次数应该是前面一段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("
");
fclose(stdin);
fclose(stdout);
return 0;
}