题目描述

对于一个长度为$n$,且下标从$1$开始编号的序列$a$,我们定义它是「合法的」,当且仅当它满足以下条件:
·$a_1=1$
·对于$i\in [1,n),a_i\leqslant a_{i+1}\leqslant a_i+1$且$a_{i+1}$为正整数
·对于任意在$a$中出现过的数$v$,记它的出现次数为$s$,则$2\leqslant s\leqslant 5$
给定一个长度为$n$的序列$a$,其中有一些位置为$0$,你需要在这些位置上任意填数,使得$a$成为一个合法的序列,并且最大化$a_n$的值。


输入格式

第一行一个数$n$,表示序列的长度。
第二行$n$个整数,第$i$个整数表示$a_i$,如果$a_i=0$,则表示这个位置没有填数。


输出格式

如果不存在合法的填数方案,则输出$−1$;否则第一行输出一个整数,表示最大的$a_n$;第二行$n$个正整数,第$i$个数表示完成填数后的序列的第$i$个元素。 如果有多组合法的解,输出任意一组


样例

样例输入1:

7
0 1 0 0 0 3 0

样例输出1:

3
1 1 2 2 3 3 3

样例输入2:

4
0 0 0 3

样例输出2:

-1


数据范围与提示

对于$30\%$的数据,$n\leqslant 1,000$;
对于另外$30\%$的数据,数据保证随机生成;
对于$100\%$的数据,$2\leqslant n\leqslant 2\times {10}^5,0\leqslant a_i\leqslant {10}^5$。


题解

对于每个位置维护两个二元组,分别是$up(x,l)$表示当前位置能填的最大值$x$和连续个数$l$;$down(x,l)$表示当前为只能填数的最小值$x$和连续个数$l$。

求$up$就是尽可能的往上升,求$down$反之。

第一问就是最后一位的最大值,至于第二问倒着扫一边即可求出。

时间复杂度:$\Theta(n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n;
int a[200001];
pair<int,int> up[200001],down[200001];
int sum[100001],ans[200001];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
if(a[1]>1){puts("-1");return 0;}
a[1]=1;
up[1]=down[1]=make_pair(1,1);
for(int i=2;i<=n;i++)
{
up[i]=make_pair(up[i-1].first,up[i-1].second+1);
down[i]=make_pair(down[i-1].first,down[i-1].second+1);
if(up[i].second>2)
{
up[i].first++;
up[i].second=1;
}
if(down[i].second>5)
{
down[i].first++;
down[i].second=1;
}
if(a[i])
{
if(up[i].first==a[i])up[i].second=min(up[i].second,2);
if(up[i].first>a[i])up[i]=make_pair(a[i],2);
if(down[i].first<a[i])down[i]=make_pair(a[i],1);
if(up[i].first<a[i]||down[i].first>a[i]){puts("-1");return 0;}
}
}
if(up[n].second==1)up[n]=make_pair(up[n-1].first,up[n-1].second+1);
printf("%d\n",up[n].first);
ans[n]=up[n].first;
sum[a[n]]=1;
for(int i=n-1;i;i--)
{
if(a[i])ans[i]=a[i];
else
{
int flag=min(ans[i+1],up[i].first);
if(sum[flag]==5)flag--;
ans[i]=flag;
}
sum[ans[i]]++;
}
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}

rp++

最新文章

  1. check_pkg函数解析
  2. cookie处理
  3. Nginx如何隐藏index.html
  4. 个性二维码开源专题&lt;液化/圆角/效果&gt;
  5. linux设备驱动编写_tasklet机制(转)
  6. [转载]移动终端浏览器初始设置apple-mobile-web-app-capable
  7. C:打印菱形(自己的方法)
  8. 基于POI和DOM4将Excel(2007)文档写进Xml文件
  9. Redis进阶实践之四Redis的基本数据类型
  10. Android okHttp网络请求库详解
  11. 物联网架构成长之路(30)-Spring Boot Admin微服务WebUI监控
  12. ASP.NET MVC学习笔记(二)笔记
  13. 为静态博客生成器WDTP移植了一款美美哒主题
  14. nodejs中function*、yield和Promise的示例
  15. ant design select 坑总结
  16. Linux的fork()写时复制原则(转)
  17. MySQL下建立表
  18. 毕向东_Java基础视频教程第20天_IO流(11~14)
  19. 002利用zabbix监控某个目录大小
  20. 无法打开mfc120.lib

热门文章

  1. Python实现BFS,DFS
  2. js常用方法和检查是否有特殊字符串和倒序截取字符串
  3. 2018-2019-2 实验四 Android程序设计
  4. Shiro那些事儿(一): Shiro初探
  5. 记录一些比较长的adb命令,复制用
  6. write(byte[] b, int off, int len)
  7. 小程序报错 Please do not register multiple Pages in undefined.js
  8. 平衡二叉搜索树AVL
  9. Write File in Vugen
  10. smb.conf免密登录文件