题目描述

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. NOIP 2022 VP游记

    总结:挂大分. HA NOIP没初中生的份,VP. CSP-S 图论专场 NOIP 数数专场. CCF 我服你. T1 看完之后,感觉不难,瞎搞了 40min+,过了大样例. 对拍不会写. T2 猜不 ...

  2. python 运行环境变为 pytest in (for) xxx.py原因

    因为本人的自定义函数名称开头为test,在.py文件内我用了unittest框架,所以环境随着变化了. 修改回去很简单,只要不使用test开头或者换个文件夹.

  3. 《CTFshow-Web入门》04. Web 31~40

    @ 目录 web31 题解 原理 web32 题解 原理 web33 题解 web34 题解 web35 题解 web36 题解 web37 题解 原理 web38 题解 原理 web39 题解 we ...

  4. 代码随想录算法训练营第二十九天| 491.递增子序列 46.全排列 47.全排列 II

      491.递增子序列 卡哥建议:本题和大家刚做过的 90.子集II 非常像,但又很不一样,很容易掉坑里.  https://programmercarl.com/0491.%E9%80%92%E5% ...

  5. Asp-Net-Core开发笔记:FrameworkDependent搭配docker部署

    前言 之前我写过一篇使用 docker 部署 AspNetCore 应用的文章,这种方式搭配 CICD 非常方便, build 之后 push 到私有的 dockerhub ,在生产服务器上 pull ...

  6. Mysql优化篇-索引优化与查询优化

    1.索引失败案列 如果查询时没有使用索引,查询语句就会扫描表中所有记录,在数据量大的情况下,查询会很慢. (1)全值匹配 (2)最佳左前缀法则 mysql可以为多个字段创建索引,一个索引可以包括16个 ...

  7. redis基本数据类型 string

    string类型 1.SET:添加或者修改已经存在的一个String类型的键值对 2.GET:根据key获取String类型的value 3.MSET:批量添加多个String类型的键值对 4.MGE ...

  8. dubbo+zookeeper+springboot远程连接,虚拟机和主机分布式操作

    dubbo+zookeeper+springboot远程连接,虚拟机和主机分布式操作 springboot版本:阿里云2.3.7 实现目标 在主机上的消费者可以调用虚拟机中生产者的接口方法 项目目录 ...

  9. 基于TRE文章的非线性模型化线性方法

    之前写过一篇有关TRE优化模型详解的博文: https://www.cnblogs.com/zoubilin/p/17270435.html 这篇文章里面的附录给出了非线性模型化线性的方式,具体内容如 ...

  10. 2023-10-07:用go语言,给定n个二维坐标,表示在二维平面的n个点, 坐标为double类型,精度最多小数点后两位, 希望在二维平面上画一个圆,圈住其中的k个点,其他的n-k个点都要在圆外。

    2023-10-07:用go语言,给定n个二维坐标,表示在二维平面的n个点, 坐标为double类型,精度最多小数点后两位, 希望在二维平面上画一个圆,圈住其中的k个点,其他的n-k个点都要在圆外. ...