【BZOJ4059】Non-boring sequences
Solution
记序列为\(a\),计算出与\(a_i\)相等的前一个元素的位置\(pre_i\),以及后一个元素的位置\(nex_i\),显然,对于那些左端点处于\((pre_i,i]\)以及右端点处于\([i,nex_i)\)的区间都可以认为是合法的。
那么我们可以将每个区间\([l,r]\)抽象成一个二维平面的点\((l,r)\),每一个元素可以使得一部分区间合法,可以抽象为一个横坐标范围为\([pre_i+1,i]\)且纵坐标范围为\([i,nex_i-1]\)的矩形。对所有矩形进行求交,如果矩形覆盖了所有的合法点(也就是一个上三角形),那么序列就是合法的,否则不合法。
但是这样跑的非常慢!在BZOJ上AC的扫描线代码在我们OJ上是完全被卡常的.....有没有更加简便的做法?
考虑\(check(l,r)\)表示所有左右端点处于\([l,r]\)的区间是否合法。则答案就是\(check(1,n)\)。
枚举\(i\in[l,r]\),一旦找到一个\(i\)使得\(pre_i<l\)且\(nex_i>r\),就停下。如果找不到,显然序列\([l,r]\)本身就不合法,直接返回\(false\)。此时我们直接可以得知,左端点处于\([l,i]\)且右端点处于\([i,r]\)的区间全部是合法的!还剩下左右断电都处于\([l,i)\)或\((i,r]\)的区间未检查,返回\(check(l,i-1)\&\&check(i+1,r)\)即可。
但是枚举这一步的复杂度我们没有保证,最坏总复杂度会达到\(O(n^2)\)。我们需要一个思想:从两头向中间同时推进枚举,直到遇到第一个所需点为止。
时间复杂度是\(T(n)=\max\{T(i)+T(n-i)+\min(n,n-i)\}=O(n\lg n)\)。
为什么呢?感性地讲,如果把递归步骤倒过来看,就是一个启发式合并!关键就在\(min(n,n-i)\)这里,每一层递归贡献的复杂度恰好是关键点与边缘的距离,而我们每次都找最靠近边缘的一个关键点,相当于启发式里面的对较小的部分进行操作的思想一样。
然后就做完了,这种两端向中间枚举的思想很值得学习和思考。
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=200005;
int n,a[N];
int dizlis[N],dizcnt;
int pre[N],nex[N],mark[N];
void Diz(){
dizcnt=n;
memcpy(dizlis,a,(dizcnt+1)*sizeof(int));
sort(dizlis+1,dizlis+1+dizcnt);
dizcnt=unique(dizlis+1,dizlis+1+dizcnt)-dizlis-1;
for(int i=1;i<=n;i++)
a[i]=lower_bound(dizlis+1,dizlis+1+dizcnt,a[i])-dizlis;
}
bool check(int l,int r){
if(l>r) return true;
int p1=l,p2=r;
while(p1<=p2){
if(pre[p1]<l&&nex[p1]>r)
return check(l,p1-1)&&check(p1+1,r);
p1++;
if(pre[p2]<l&&nex[p2]>r)
return check(l,p2-1)&&check(p2+1,r);
p2--;
}
return false;
}
int Main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
Diz();
for(int i=1;i<=dizcnt;i++) mark[i]=0;
for(int i=1;i<=n;i++)
pre[i]=mark[a[i]],mark[a[i]]=i;
for(int i=1;i<=dizcnt;i++) mark[i]=n+1;
for(int i=n;i>=1;i--)
nex[i]=mark[a[i]],mark[a[i]]=i;
puts(check(1,n)?"non-boring":"boring");
return 0;
}
int main(){
int T;
scanf("%d",&T);
while(T--) Main();
return 0;
}
【BZOJ4059】Non-boring sequences的更多相关文章
- 【bzoj4059】[Cerc2012]Non-boring sequences 分治
题目描述 我们害怕把这道题题面搞得太无聊了,所以我们决定让这题超短.一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子序列里至少存在一个数字只出现一次.给定一个整数序列, ...
- 【题解】CF264B Good Sequences
[题解]CF264B Good Sequences 具有很明显的无后效性. 考虑\(dp\). 考虑初始条件,显然是\(dp(0)=0\) 考虑转移,显然是\(dp(t)=max(dp[k])+1\) ...
- 【LeetCode】Repeated DNA Sequences 解题报告
[题目] All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: &quo ...
- 【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 (正解暴力)
4059: [Cerc2012]Non-boring sequences Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 440 Solved: 16 ...
- 【BZOJ4059】Non-boring sequences(分析时间复杂度)
题目: BZOJ4059 分析: 想了半天没什么想法,百度到一个神仙做法-- 设原数列为 \(a\),对于每一个 \(i\) 求出前一个和后一个和 \(a_i\) 相等的位置 \(pre[i]\) 和 ...
- 【leetcode】Repeated DNA Sequences(middle)★
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...
- 【Leetcode】【Medium】Repeated DNA Sequences
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...
- 【HDOJ】4358 Boring counting
基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径.从而将每个查询转换成区间,表示从该结点到叶子结点的路径.离线做,按照右边界升序排序.利用树状数组区间修改.树状数组表示有K个数据 ...
- 【HDOJ】3518 Boring Counting
后缀数组2倍增可解. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 10 ...
随机推荐
- MPVUE多环境定义后台URL
小程序选定了mpvue作为开发框架,搭建开发环境和构建环境.自从用了Travis和Jenkins之后,再也回不到手工构建的时代了. 目的-自动构建 web项目中,自从前后台分离的结构形成,就形成了一个 ...
- Netty源码分析第1章(Netty启动流程)---->第1节: 服务端初始化
Netty源码分析第一章: Server启动流程 概述: 本章主要讲解server启动的关键步骤, 读者只需要了解server启动的大概逻辑, 知道关键的步骤在哪个类执行即可, 并不需要了解每一步的 ...
- Nginx内置的嵌入变量
Nginx核心模块ngx_http_core_module自带有许多内置嵌入的变量,这些变量方便我们配置和使用nginx,在nginx的配置文件中我们可以以$开头直接使用这些变量,这些变量表示客户端请 ...
- netcore如何引用package?
netcore项目引用dll包,分如下三种: 1.引用网络包 从nuget获取,然后引入,使用命令:dotnet add package 包名 然后:dotnet restore 2.引用同解决方案的 ...
- javaweb 安全传输签名机制
java web传输中的安全签名说明: 对请求中的数据 Key对进行签名,最终生成一个签名字符串,标记为sign:"djflw8wejwl9w0ejwlush8fw9ew9",位数 ...
- Dailu Scrum (2015/10/27)
在周日晚上PM已经为大家分配了部分的代码修改工作,今天晚上PM召集了被分配代码工作的3个DEV一起讨论要求修改的代码.在共同讨论的过程中确有发现以下代码的不规范之处,PM当即要求我们先要修改规范代码的 ...
- java程序设计第二次实验报告
北京电子科技学院(BESTI) 实验报告 课程:数据结构 班级:1352 姓名:何伟钦 学号:20135223 成绩: 指导教师:娄嘉鹏 实验日期: ...
- java 实验一
步骤 耗时h 百分比% 需求分析 0.3h 7.5 设计 2.5h 62.5 代码实现 0.5h 12.5 测试 0,2h 5 分析总结 0.5h 12.5 实验一 截图 实验二: 实验三 实现 ...
- HDU 1170 Shopping Offers 离散+状态压缩+完全背包
题目链接: http://poj.org/problem?id=1170 Shopping Offers Time Limit: 1000MSMemory Limit: 10000K 问题描述 In ...
- 团队作业7——第二次项目冲刺(Beta版本12.09——12.10)
1.当天站立式会议照片 本次会议在5号公寓3楼召开,本次会议内容:①:熟悉每个人想做的模块.②:根据项目要求还没做的完成. 2.每个人的工作 经过会议讨论后确定了每个人的分工 组员 任务 陈福鹏 倒计 ...