题目描述

Note that the memory limit in this problem is less than usual.

Let's consider an array consisting of positive integers, some positions of which contain gaps.

We have a collection of numbers that can be used to fill the gaps. Each number from the given collection can be used at most once.

Your task is to determine such way of filling gaps that the longest increasing subsequence in the formed array has a maximum size.

输入格式

The first line contains a single integer $ n $ — the length of the array ( $ 1<=n<=10^{5} $ ).

The second line contains $ n $ space-separated integers — the elements of the sequence. A gap is marked as "-1". The elements that are not gaps are positive integers not exceeding $ 10^{9} $ . It is guaranteed that the sequence contains $ 0<=k<=1000 $ gaps.

The third line contains a single positive integer $ m $ — the number of elements to fill the gaps ( $ k<=m<=10^{5} $ ).

The fourth line contains $ m $ positive integers — the numbers to fill gaps. Each number is a positive integer not exceeding $ 10^{9} $ . Some numbers may be equal.

输出格式

Print $ n $ space-separated numbers in a single line — the resulting sequence. If there are multiple possible answers, print any of them.

1.5s,128MB

LIS 问题有两种优化方式,所以这题也有两种做法。

1. 二分

考虑用二分维护 \(dp_{i}\) 表示目前长度为 \(i\) 的 序列里面树最小的是 \(i\),然后对于固定的数二分去修改,不固定的可以把 \(m\) 个数排序后维护一个指针扫过去找到第一个大于 \(a_i\) 的,这里复杂度 \(nk\)

但是要输出方案,而且不可能开的下 \(nk\) 的区间去记录每个点的前驱。对于每个正常的数仍然记录下他的前驱是哪个位置。设现在第 \(x\) 个位置是 LIS 中的第 \(p\) 个数,填了 \(y\)。那么如果 \(a_x\ne -1\),LIS 中 \(p-1\) 个数一定是它的前驱,否则我们就先找一下是否存在一个 \(dp\) 值为 \(p-1\) 并且 \(a_j\ne -1\) 的 \(j\),还要满足 \(a_j<y\),如果存在 \(p-1\) 位可以填他,否则 \(p-1\) 位就是上一个 -1 出现的地方。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int lst[N],mx,id[N],n,k,m,a[N],b[N],dp[N],ls[N],fr[N];//ls是值,fr 是位ç½
multiset<int>s;
vector<int>g[N];
int read()
{
int 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-48,ch=getchar();
return s*f;
}
void sou(int x,int y,int p)//在 x 处,填了y,子序列第p项
{
//printf("%d %d %d\n",x,y,p);
if(p==1)
{
if(a[x]==-1)
{
a[x]=y;
s.erase(s.lower_bound(y));
}
return;
}
if(a[x]==-1)
{
a[x]=y;
s.erase(s.lower_bound(y));
vector<int>::iterator k=lower_bound(g[p-1].begin(),g[p-1].end(),x);
if(k==g[p-1].begin()||a[*(k-1)]>=y)
sou(lst[x],*(lower_bound(b+1,b+m+1,y)-1),p-1);
else
sou(*(k-1),a[*(k-1)],p-1);
}
else
sou(ls[x],fr[x],p-1);
}
int main()
{
memset(dp,0x7f,sizeof(dp));
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
m=read();
for(int i=1;i<=m;i++)
s.insert(b[i]=read());
sort(b+1,b+m+1);
for(int i=1;i<=n;i++)
{
if(!~a[i-1])
lst[i]=i-1;
else
lst[i]=lst[i-1];
if(~a[i])
{
int t=lower_bound(dp+1,dp+n+1,a[i])-dp;
dp[t]=a[i],id[t]=i;
ls[i]=id[t-1],fr[i]=dp[t-1];
g[t].push_back(i);
//printf("%d %d\n",i,t);
}
else
{
int r=n;
for(int j=m;j;j--)
{
while(r^1&&dp[r-1]>=b[j])
--r;
dp[r]=b[j],id[r]=i;
}
}
}
for(int i=1;i<=n;i++)
if(dp[i+1]==0x7f7f7f7f)
mx=i,i=n;
//printf("%d\n",mx);
sou(id[mx],dp[mx],mx);
for(int i=1;i<=n;i++)
{
if(!~a[i])
{
a[i]=*s.begin();
s.erase(s.begin());
}
}
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
}

2.数据结构

定义 \(dp_i\) 为以 \(i\) 为结尾的 LIS 最长是多少,这里我们忽略掉 -1 的存在。

设 \(c_i\) 为可以填的数中有多少个不超过 \(i\) 的数,\(a_i\) 为原数组中前 \(i\) 个数有多少个 -1

然后 \(dp_i=\max\limits_{j<i}dp_j+\min(c_{a_i}-c_{a_j},s_i-s_j)\)。

把 min 拆掉,就变成了一个三维偏序,CDQ 分治即可。

方案可以通过记录 CDQ 时线段树上的最大值来源就行了。

代码懒得写了

[CF568E] Longest Increasing Subsequence的更多相关文章

  1. [LeetCode] Longest Increasing Subsequence 最长递增子序列

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  2. [tem]Longest Increasing Subsequence(LIS)

    Longest Increasing Subsequence(LIS) 一个美丽的名字 非常经典的线性结构dp [朴素]:O(n^2) d(i)=max{0,d(j) :j<i&& ...

  3. [LintCode] Longest Increasing Subsequence 最长递增子序列

    Given a sequence of integers, find the longest increasing subsequence (LIS). You code should return ...

  4. Leetcode 300 Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  5. [LeetCode] Longest Increasing Subsequence

    Longest Increasing Subsequence Given an unsorted array of integers, find the length of longest incre ...

  6. The Longest Increasing Subsequence (LIS)

    传送门 The task is to find the length of the longest subsequence in a given array of integers such that ...

  7. 300. Longest Increasing Subsequence

    题目: Given an unsorted array of integers, find the length of longest increasing subsequence. For exam ...

  8. SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治

    Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://a ...

  9. leetcode@ [300] Longest Increasing Subsequence (记忆化搜索)

    https://leetcode.com/problems/longest-increasing-subsequence/ Given an unsorted array of integers, f ...

  10. [Leetcode] Binary search, DP--300. Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

随机推荐

  1. CDC一键入湖:当 Apache Hudi DeltaStreamer 遇见 Serverless Spark

    Apache Hudi的DeltaStreamer是一种以近实时方式摄取数据并写入Hudi表的工具类,它简化了流式数据入湖并存储为Hudi表的操作,自 0.10.0 版开始,Hudi又在DeltaSt ...

  2. 如何理解SpringBoot的Starter

    Starter是SpringBoot的四大核心功能特性之一,除此之外,SpringBoot还有自动装配,Actuator监控等特性 SpringBoot里面的这些特性,都是为了让开发者在开发基于Spr ...

  3. 小知识:vi 查找如何不区分大小写

    在使用vi查找数据库的truncate记录日志时,发现对应语句夹杂了大小写,不够规范: 而vi默认查找是区分大小写的,如何不区分大小写查找指定内容呢? 有两种方式: (1)在查找指令后面额外加上\c标 ...

  4. 创建及管理DSW实例

      机器学习PAI 产品概述 快速入门 操作指南 准备工作 工作空间管理 AI计算资源管理 AI开发 开发流程 快速开始 智能标注(iTAG) 可视化建模(PAI-Designer) 交互式建模(PA ...

  5. BizSpring在线商城常见问题

    一.什么是BizSpring在线商城? BizSpring在线商城是一个用java语言开发的完全开源的网络商城平台.该项目已经经历多次迭代升级是一个的成熟的在线商城解决方案,它具有轻量级,易于维护,操 ...

  6. jmeter生成HTML性能测试报告(非GUI的命令)

    非GUI的命令(在cmd执行即可 不需要打开jmeter) 使用命令:jmeter  -n  -t  [jmx file]  -l  [jtl file]  -e  -o   [report path ...

  7. 基于matomo实现业务数据埋点采集上报

    matomo是一款Google-analytics数据埋点采集上报的平替方案,可保护您的数据和客户的隐私:正如它官网的slogan: Google Analytics alternative that ...

  8. Node.js中常用的设计模式有哪些?

    本文由葡萄城技术团队首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 设计模式简介 设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可 ...

  9. 毕业三年,月薪30K,我想跟你聊聊!

    大家好,我是冰河~~ 很多读者私信问我,自己工作三年多了,随着工作年限的不断增长,感觉自己的技术水平与自己的工作年限严重不符.想跳槽出去换个新环境吧,又感觉自己的能力达不到心仪公司的标准,即使投了简历 ...

  10. 网络基础-OSI七层vsTCP/UDP四层 五层 数据封装

    1.0 网络基础 1.1 网络是什么? 网络是信息传输.接收.共享的虚拟平台,通过它把各个点.面.体的信息联系到一起,从而实现这些资源的共享 网络分类:局域网 ,城域网,广域网 1.2 数据通信方式 ...