题目描述

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. 原神盲盒风格:AI绘画Stable Diffusion原神人物公仔实操:核心tag+lora模型汇总

    本教程收集于:AIGC从入门到精通教程汇总 在这篇文章中,我们将深入探讨原神盲盒的艺术风格,以及如何运用AI绘画技术(Stable Diffusion)--来创造原神角色公仔.我们将通过实践操作让读者 ...

  2. DesignPattern-part3

    title: "modern C++ DesignPattern-Part3" date: 2018-04-12T19:08:49+08:00 lastmod: 2018-04-1 ...

  3. zbolg首页-文章内标签调用代码

    {if count($lhantItem.Tags)>0}{foreach $lhantItem.Tags as $i => $tag} <a href='{$tag.Url}' t ...

  4. 「codeforces - 1208F」Bits and Pieces

    link. 考虑把原问题写成一个在 \(\left(\log_2 \max v \right) \times n\) 的矩阵里选出三列,我们首先预处理出 \(j \cap q\).具体,我们需要对于每 ...

  5. 「sdoi2019 - D2T2」移动金币

    对 @command_block 没有 implementation 做法的细化.理论来说可以通过,但因为我实现得较劣无法通过.:( 把金币中的空隙看作石子,就是一个阶梯 Nim 的模型(有总共 \( ...

  6. lvm格式化挂载分区

    1.从物理磁盘创建lvm分区 物理磁盘 /dev/sdb 20G 2.使用fdisk工具创建lvm分区 3.修改默认的分区类型 4.查看新建的分区 5.创建物理卷pv 6.创建逻辑卷组vg,并查看详情 ...

  7. mpi转以太网连接200PLC转以太网modbusTCP服务器通信配置方法

    兴达易控200PLC转以太网modbusTCP服务器通信配置方法 产品简介 兴达易控PPI-ETH-XD1.0用于西门子S7-200/SMART S7-200PLC的以太网数据采集,非常方便构建生产管 ...

  8. 利用python将数据写入CSV文件中

    利用python将数据写入CSV文件中 全部代码如下: import csv # 1.创建文件对象 f = open('cav_file.csv', 'w', encoding='utf-8', ne ...

  9. Chapter 57. Multi-project Builds

    http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects The po ...

  10. 创建vue项目并搭建JSONSERVER

    1.该前提是你已经搭建好vue-cli脚手架,开始创建一个新项目,输入 vue init webpack demo(demo是自定义项目名). 2.cd demo 进入项目安装依赖 3.在已经创建的项 ...