4970: [ioi2004]empodia 障碍段

Time Limit: 10 Sec  Memory Limit: 128 MB

Description

古数学及哲学家毕氏相信自然之本质为数学。现代生物学家研究生物数列(biosequences)。 生物数数为满足下列
条件之 M 个整数所成的数数:
1: 包含从 0, 1, …, 到 M - 1 的所有数字
2: 起始数字为 0, 最后一个数字为 M - 1
?2:数列中 E+1 不可以紧接在 E 之后
生物数数的连续子数列称为数段(segments)。如果一个数段的起点为该数段最小的数字, 终点为该数段最大的数
字且与起点不是同一个数字,且介于这两个数字之间所有的整数都出现在这个数段中, 则称这个数段为框段(frame
d interval),如果框段中并不包含题名小的框段,则称之为障碍段(empodio)。以(0,3,5,4,6,2,1,7)这个生物数
列为例。 整个生物数?是一个框段, 可是它包含了另外一框段 (3,5,4,6) ,因此该生物数列是障碍段。而框段 (
3,5,4,6) 并不包含任何更短的框段所以它是一个障碍段,而且是此生物数列中唯一的障碍段。请写一个程序, 在
输入生物数列后, 输出所有的障碍段 (empodia 为 empodio的复数形)。

Input

第一行为单一整数M,代表生物数列的长度。 
生物数列中的数字依序出现在接下来的 M 行,每一行有一个整数
M≤1100000

Output

第一行为一整数H,代表该生物数列中的障碍段的个数。
接下来的 H 行,将每一个障碍段,依照起点在原输入生物数列中出现的顺序,依序输出。
每行以2个整数A 与 B 代表一个障碍段并以一个空白分开
原输入生物数列第 A 个元素为该障碍段之起点,而第 B 个元素为该障碍段之终点

Sample Input

8
0
3
5
4
6
2
1
7

Sample Output

1
2 5
 
  Nick大佬出的联赛模拟题……这已经不是第一个在联赛模拟上出IOI题的人了?不过可能是我唯一能切的题吧,还是在机缘巧合之下。
  放在二维平面上就是一个正方形网格,然后枚举左下角,看怎么快速计算右上角。
  首先左下角的点是作为矩阵的最小值的,所以可以通过一次单调栈从右往左找到右边界最值。
  其次,右上角的点作为矩阵的最大值,一定在从右往左递减的单调栈_2里。因为单调栈对应关系是唯一的,所以可以把它看成一棵树,从右往左连边,根节点为(n,n),答案就只有可能出现在某节点的祖先链上。
  对应的式子是A[i]-A[j]=i-j,即A[i]-i=A[j]-j。我们在单调栈_2构成的树上dfs,维护一下一条链上的信息,用一个桶记录一下A[i]-i最前面的位置就可以了。
  最后得到了不超过n个矩阵(区间),去重去包含就是很简单的事情了。

#include <map>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define rg register
#define FILE "empodia"
using namespace std; const int N = ;
int n,A[N],sta[N],nxt_1[N],nxt_2[N],Ans,bin[N<<],R[N];
vector<int>G[N]; inline int gi(){
rg int x=,res=;rg char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')res^=;ch=getchar();}
while(ch>=''&&ch<='')x=x*+ch-,ch=getchar();
return res?x:-x;
} inline void link(int u,int v){
G[u].push_back(v);
} inline void getnxt_1(rg int tp=){
sta[]=n+;
for(rg int i=n;i>=;--i){
while(tp && A[sta[tp]]<A[i])tp--;
nxt_1[i]=sta[tp];sta[++tp]=i;
link(nxt_1[i],i);
}
} inline void getnxt_2(rg int tp=){
sta[]=n+;
for(rg int i=n;i>=;--i){
while(tp && A[sta[tp]]>A[i])tp--;
nxt_2[i]=sta[tp];sta[++tp]=i;
}
} inline void dfs(int x){
int g=A[x],qt=bin[g];
if(bin[g]<=nxt_2[x])R[x]=bin[g];
bin[g]=x;
for(int i=,j=G[x].size();i<j;i++)
dfs(G[x][i]);
bin[g]=qt;
} int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
n=gi();memset(bin,,sizeof(bin));
for(rg int i=;i<=n;++i)A[i]=gi()+;
getnxt_1();getnxt_2();
memset(R,,sizeof(R));
for(int i=;i<=n;++i)A[i]=A[i]-i+n;
dfs(n);
for(int i=n,Mx=R[];i>=;--i){
if(R[i]>Mx)R[i]=R[];
Mx=min(Mx,R[i]);
}
for(int i=;i<=n;++i)if(R[i]<=n)Ans++;
printf("%d\n",Ans);
for(int i=;i<=n;++i)
if(R[i]<=n)printf("%d %d\n",i,R[i]);
fclose(stdin);fclose(stdout);
return ;
}

障碍段

BZOJ4970 IOI2004 empodia障碍段的更多相关文章

  1. BZOJ4970 : [ioi2004]empodia 障碍段

    通过两遍单调栈求出每个点作为最小值往右延伸到$g[i]$,作为最大值往左延伸到$f[i]$. 那么一个区间$[i,j]$可行当且仅当$g[i]\geq j$.$f[j]\leq i$且$i-a[i]= ...

  2. CF954F Runner's Problem(动态规划,矩阵快速幂)

    CF954F Runner's Problem(动态规划,矩阵快速幂) 题面 CodeForces 翻译: 有一个\(3\times M\)的田野 一开始你在\((1,2)\)位置 如果你在\((i, ...

  3. 本地管理表空间(LMT)与自动段空间管理(ASSM)概念

    创建表空间时,extent management local 定义本地管理表空间(LMT),segment space management auto 定义自动段空间管理(ASSM). extent ...

  4. 进阶篇:2.1)DFMA实施障碍和关键

    本章目的:了解DFMA实施障碍与关键. 1.实施的障碍 面向制造和装配的产品开发能够降低产品成本.提高产品质量.缩短产品开发周期,但是,由于传统产品开发思想和各种条件的限制,实施面向制造和装配的产品开 ...

  5. 跨越语言的障碍:C++/CLI 调用 C#

    首先我想投诉一下博客园首页右边栏的广告..最近总是出现很恐怖的整容脸的广告.真的是吓坏了.=.=大家有同感吗? 博客园前一阵子掀起了语言的广泛讨论,事实上语言的争执在整个程序员圈子也没有停止过.以我个 ...

  6. mysql向表中某字段后追加一段字符串:

    mysql向表中某字段后追加一段字符串:update table_name set field=CONCAT(field,'',str) mysql 向表中某字段前加字符串update table_n ...

  7. WPF自定义RoutedEvent事件代码段

    今天在写东西的时候,发现常用的代码段里没有RoutedEvent的,因此,写了一个代码段,方便以后使用,顺便记录一下,如何做代码段. 1.在项目中新建一个XML文件,将扩展名修改为snippet. 2 ...

  8. mssql 字增自段怎样重置(重新自增)|清空表已有数据

    方法1 -- 清空已有数据,并且将自增自段恢复从1开始计数 truncate table 表名 方法2 -- 不清空已有数据,但将自增自段恢复从1开始计数 dbcc checkident(表名,RES ...

  9. u-boot源码分析之C语言段

    题外话: 最近一直在学习u-boot的源代码,从代码量到代码风格,都让我认识到什么才是真正的程序.以往我所学到的C语言知识和u-boot的源代码相比,实在不值一提.说到底,机器都是0和1控制的.感觉这 ...

随机推荐

  1. 状态机编程思想(2):删除代码注释(目前支持C/C++和Java)

    有时为了信息保密或是单纯阅读代码,我们常常需要删除注释. 之前考虑过正则表达式,但是感觉实现起来相当麻烦.而状态机可以把多种情况归为一类状态再行分解,大大简化问题.本文就是基于状态机实现的. 删除C/ ...

  2. azure备份虚拟机

    备份 azure虚拟机 提前创建了一个linux虚拟机,位置是chinaeast. 如果我们需要备份的虚拟机分别在中国东部和北部,那么需要在两个位置都创建备份库. 创建库 登录经典门户,新建-> ...

  3. SVN服务器

    什么是SVN服务器? 1.协助多人开发的代码管理器: 2.会记录代码是谁写的,并且可以回退到任意版本: 3.冲突解决: 4.升级(项目分支). SVN的搭建: 1.在服务器端下载SVN服务器,一个项目 ...

  4. apache通过AD验证

    ## apache通过AD验证 #yum install httpd mod_authz_ldap#安装apahce的ldap模块yum install mod_authz_ldap -y #配置ap ...

  5. 导入Excel 文件(图片和文字)NPOI+BootStrap fileinput 插件 的结合使用

    1.页面代码: <!DOCTYPE html><html><head> <meta name="viewport" content=&qu ...

  6. eclipse 常用插件 整理

    开发过程中的常用Eclipse插件,按字母排序: (1)    AmaterasUML        介绍:Eclipse的UML插件,支持UML活动图,class图,sequence图,usecas ...

  7. 乘积最大洛谷p1018

    题目描述 今年是国际数学联盟确定的“2000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得 ...

  8. SQL Server 日志清理

    --SQL2005: Backup Log DNName with no_log --这里的DNName是你要收缩的数据库名,自己注意修改下面的数据库名,我就不再注释了. go dump transa ...

  9. ubuntu更换开机动画

    ubuntu更换启动动画 作为一个个用linux作为桌面环境,并且完全替代了windows的来说,怎么折腾好看,是一个重要的问题,而Ubuntu的开机动画,那紫色的画面,ubuntu那几个大字,实在丑 ...

  10. poj 2905 双向队列(待补充)

    Parallel Computer Simulator   Description Programs executed concurrently on a uniprocessor system ap ...