题目大意:给你一个数组,数组是经过q次区间覆盖后的结果,第i次覆盖是把区间内的值赋值为i,其中有若干个地方数值未知(就是0),让你判断这个数组是否可以经过覆盖后得到的,如果可以,输出任意一种可行数组。

思路:不合法的情况只有2种。1:两个相同的数字中间出现了比它小的数字,比如: 6 5 6 就不合法,因为覆盖6的时候是覆盖连续的一段区间,而5比6先覆盖,所以这种情况不存在。我赛后看AC代码的时候发现有的人只是判断是否出现谷形的情况,这种是不对的。

比如这种样例:3 3 3 1 2 这种判断方法会输出NO,但实际上却可以覆盖。那么怎么找任意区间内的最小值呢?线段树啊(比赛结束前10分钟才想到。。。)。

2:最大值没出现过而且没有0,因为最大值是最后一次覆盖的,所以肯定有最大值。

那么我们就可以写代码了:

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<string>
#include<map>
#include<set>
#include<bitset>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#define INF 0x3f3f3f3f
#define LL long long
#define mk(a,b) make_pair(a,b)
#define pii pair<int,int>
using namespace std;
const int maxn=200010;
map<int,int> mp;
int a[maxn],mi[maxn];
bool vis[maxn];
int minv[4*maxn];
int ql,qr;
int query(int o,int l,int r){//查询最小值
int mid=l+(r-l)/2,ans=INF;
if(ql<=l&&r<=qr)return minv[o];
if(ql<=mid)ans=min(ans,query(o*2,l,mid));
if(mid<qr)ans=min(ans,query(o*2+1,mid+1,r));
return ans;
}
void build(int o,int l,int r){
if(l==r){
minv[o]=a[l];
return;
}
int mid=l+(r-l)/2;
build(o*2,l,mid);
build(o*2+1,mid+1,r);
minv[o]=min(minv[o*2],minv[o*2+1]);
}
int main(){
int n,m,mi=INF,mx=0,cnt=0;
bool flag=1;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
mx=max(mx,a[i]);
if(a[i]==0){//为了方便建线段树,把0赋值为INF
a[i]=INF;
cnt++;
}
}
if(mx<m&&cnt==0){//第二种情况
printf("NO\n");
return 0;
}
build(1,1,n);//建树
for(int i=1;i<=n;i++){
if(a[i]==INF){
continue;
}
if(vis[a[i]]){//如果之前出现过
ql=mp[a[i]],qr=i;
if(query(1,1,n)<a[i]){//如果小于a[i]值
flag=0;
break;
}
}
vis[a[i]]=1;
mp[a[i]]=i;
}
if(flag==0){//情况1
printf("NO\n");
return 0;
}
for(int i=1,j;i<=n;i++){//从前往后扫一遍
if(a[i]!=INF)continue;
else{
if(mx<m)a[i]=m;//如果最大值没出现,就赋值为最大值
else a[i]=a[i-1];//否则赋值为他前面的值
mx=max(mx,a[i]);
}
}
for(int i=n,j;i>=1;i--){
if(a[i]!=INF&&a[i]!=0)continue;//防止a[1]为0的情况
else{
if(mx<m)a[i]=m;
else a[i]=a[i+1];
mx=max(mx,a[i]);
}
}
printf("YES\n");
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
}

  

Codeforces #504(div1+div2) 1023D Array Restoration(线段树)的更多相关文章

  1. CF 1023D Array Restoration - 线段树

    题解 非常容易想到的线段树, 还可以用并查集来. 还有一位大神用了$O(n)$ 就过了Orz 要判断是否能染色出输入给出的序列,必须满足两个条件: 1. 序列中必须存在一个$q$ 2. 两个相同的数$ ...

  2. CodeForces 266E More Queries to Array...(线段树+式子展开)

    开始觉得是规律题的,自以为是的推了一个规律,结果测试数据都没过....看了love神的博客才发现只是把式子展开就找到规律了.不过挺6的是我虽然想错了,但是维护的的东西没有错,只是改改(改了进两个小时好 ...

  3. codeforces 482B. Interesting Array【线段树区间更新】

    题目:codeforces 482B. Interesting Array 题意:给你一个值n和m中操作,每种操作就是三个数 l ,r,val. 就是区间l---r上的与的值为val,最后问你原来的数 ...

  4. Codeforces E. Interesting Array(线段树)

    题目描述: D. Interesting Arraytime limit per test1 secondmemory limit per test256 megabytesinputstandard ...

  5. codeforces div2 603 E. Editor(线段树)

    题目链接:https://codeforces.com/contest/1263/problem/E 题意:一个编译器,每次输入一些字符,R表示光标右移,L表示光标左移,然后有一些左括号(  和 右括 ...

  6. Codeforces 671C - Ultimate Weirdness of an Array(线段树维护+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 *2800 的 DS,不过还是被我自己想出来了 u1s1 这个 D1C 比某些 D1D 不知道难到什么地方去了 首先碰到这类问题我们肯定考 ...

  7. CodeForces Round #179 (295A) - Greg and Array 一个线段树做两次用

    线段树的区间更新与区间求和...一颗这样的线段树用两次... 先扫描1~k...用线段树统计出每个操作执行的次数... 那么每个操作就变成了 op. l  , op.r , op.c= times* ...

  8. Codeforces 718C. Sasha and Array(线段树)

    传送门 解题思路: 这道题给了我们一个崭新的角度来看线段树. 我们常常使用的线段树是维护区间的函数的. 这里呢,提示我们线段树其实还可以维护递推. 美好的矩阵递推性质支持了这一功能. 或者说,对于递推 ...

  9. CCPC-Wannafly Winter Camp Day1 Div1 - 夺宝奇兵 - [贪心+线段树]

    题目链接:https://zhixincode.com/contest/3/problem/J?problem_id=43 样例输入 1 4 1110 11 110 21 210 31 315 415 ...

随机推荐

  1. Redis 存储机制

    Redis存储机制分成两种Snapshot和AOF.无论是那种机制,Redis都是将数据存储在内存中. Snapshot工作原理: 是将数据先存储在内存,然后当数据累计达到某些设定的伐值的时候,就会触 ...

  2. 使用log4j的邮件功能

    Log4j的邮件功能能够为我们做这样的事情----当程序运行完的时候,或者正在运行也是可以的,它将程序的日志通过邮件的方式发到你的邮箱上. 这样,对于程序运行的控制就不用每次都跑到机器上去看日志文件这 ...

  3. 用urliso把linux刻录U盘失败无数次。 用unetbootin试试可以启动的。

    我用的是ubuntu 16.04 lts 画面挺好用的.

  4. java学习笔记 --- IO(1)

    1.File类:文件和目录(文件夹)路径名的抽象表示形式,把文件或者目录(文件夹)都封装成File对象 1.构造方法 File(String pathname):根据一个路径得到File对象 File ...

  5. @angular/cli项目构建--http(2)

    客户端GET设置参数查询: search() { const params = new HttpParams() .set('userName', this.userName) .set('fullN ...

  6. redhat5.8 alt+ctrl+f1 黑屏

    /********************************************************************** * redhat5.8 alt+ctrl+f1 黑屏 * ...

  7. golang实现模拟键盘按键

    公司前段时间要我写个小项目需要可以局域网内一个ipad控制另一台pc上的键盘输入,github上找了找,居然有个robotgo库这么神级的存在,感觉go的库真是越来越多了,虽然大部分都是第三方的.ht ...

  8. CodeForces - 154C:Double Profiles (hash+排序)

    You have been offered a job in a company developing a large social network. Your first task is conne ...

  9. 记一次内存溢出的分析经历——使用thrift

    背景: 有一个项目做一个系统,分客户端和服务端,客户端用c++写的,用来收集信息然后传给服务端(客户端的数量还是比较多的,正常的有几千个), 服务端用Java写的(带管理页面),属于RPC模式,中间的 ...

  10. Ubuntu下部署GitLab-——基于14.04系统

    搭建GitLab的目的: 方便公司开发管理代码 GitLab实现的功能: 1.关闭了gitlab的注册功能 2.修改了默认端口 3.汉化 0.前期准备 # 环境 Ubuntu 14.04 root@i ...