【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 (正解暴力)
4059: [Cerc2012]Non-boring sequences
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 440 Solved: 160
[Submit][Status][Discuss]
Description
我们害怕把这道题题面搞得太无聊了,所以我们决定让这题超短。一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子序列里至少存在一个数字只出现一次。给定一个整数序列,请你判断它是不是不无聊的。
Input
第一行一个正整数T,表示有T组数据。每组数据第一行一个正整数n,表示序列的长度,1 <= n <= 200000。接下来一行n个不超过10^9的非负整数,表示这个序列。
Output
对于每组数据输出一行,输出"non-boring"表示这个序列不无聊,输出"boring"表示这个序列无聊。
Sample Input
5
1 2 3 4 5
5
1 1 1 1 1
5
1 2 3 2 1
5
1 1 2 1 1
Sample Output
boring
non-boring
boring
HINT
Source
Solution
不想多说什么
首先预处理出每个数字,上一次出现的位置$pre[i]$,下一次出现的位置$suf[i]$,显然,对于区间是满足独一无二的,当左端点在$[pre[i]+1,i]$右端点在$[i,suf[i]-1]$
然后我们把它们放到平面上,<l,r>表示一个点,那么满足的情况,显然是一个矩形
那么我们把这些所有的矩形都建出来,然后扫描线。
如果这些矩形的并覆盖所有合法点,那么就是non-boring,否则是boring
问题在于,这不是正解!!!!正解是神奇的爆搜,转别人的博客 : 传送门
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 200010
int T,N,A[MAXN];
struct SegmentTreeNode{int minn,tag,l,r;}tree[MAXN<<];
inline void Update(int now) {tree[now].minn=min(tree[now<<].minn,tree[now<<|].minn);}
inline void PushDown(int now)
{
if (!tree[now].tag || tree[now].l==tree[now].r) return;
int tag=tree[now].tag; tree[now].tag=;
tree[now<<].minn+=tag; tree[now<<].tag+=tag;
tree[now<<|].minn+=tag; tree[now<<|].tag+=tag;
}
void BuildTree(int now,int l,int r)
{
tree[now].l=l; tree[now].r=r; tree[now].minn=; tree[now].tag=;
if (l==r) return;
int mid=(l+r)>>;
BuildTree(now<<,l,mid);
BuildTree(now<<|,mid+,r);
Update(now);
}
void Change(int now,int L,int R,int D)
{
PushDown(now);
int l=tree[now].l,r=tree[now].r;
if (L<=l && R>=r) {tree[now].tag+=D; tree[now].minn+=D; return;}
int mid=(l+r)>>;
if (L<=mid) Change(now<<,L,R,D);
if (R>mid) Change(now<<|,L,R,D);
Update(now);
}
int Query(int now,int L,int R)
{
PushDown(now);
int l=tree[now].l,r=tree[now].r;
if (L<=l && R>=r) return tree[now].minn;
int mid=(l+r)>>,re=0x7fffffff;
if (L<=mid) re=min(re,Query(now<<,L,R));
if (R>mid) re=min(re,Query(now<<|,L,R));
return re;
}
struct LineNode
{
int x,y1,y2,f;//y1>y2
LineNode (int x=,int y1=,int y2=,int f=)
: x(x),y1(y1),y2(y2),f(f) {}
bool operator < (const LineNode & A) const
{return x==A.x? y1<A.y1 : x<A.x;}
}Line[MAXN<<];
int ls[MAXN<<],tp,pre[MAXN],suf[MAXN],last[MAXN];
int main()
{
T=read();
while (T--)
{
N=read();
tp=;
for (int i=; i<=N; i++) ls[++tp]=A[i]=read();
sort(ls+,ls+tp+);
tp=unique(ls+,ls+tp+)-ls-;
for (int i=; i<=N; i++) A[i]=lower_bound(ls+,ls+tp+,A[i])-ls;
for (int i=; i<=N; i++) pre[i]=suf[i]=last[i]=;
for (int i=; i<=N; i++)
{
if (!last[A[i]]) pre[i]=;
else suf[last[A[i]]]=i-,pre[i]=last[A[i]]+;
last[A[i]]=i;
}
for (int i=; i<=N; i++) if (!suf[i]) suf[i]=N;
// for (int i=1; i<=N; i++) printf("%d %d %d \n",i,pre[i],suf[i]);
tp=;
for (int i=; i<=N; i++)
{
Line[++tp]=LineNode(pre[i],suf[i],i,);
Line[++tp]=LineNode(i+,suf[i],i,-);
}
sort(Line+,Line+tp+);
// for (int i=1; i<=tp; i++)
// printf("%d %d %d %d\n",Line[i].x,Line[i].y2,Line[i].y1,Line[i].f);
BuildTree(,,N);
bool flag=;
for (int X=,i=; X<=N; X++)
{
while (i<=tp && Line[i].x==X)
Change(,Line[i].y2,Line[i].y1,Line[i].f),i++;
if (Query(,X,N)==) {flag=; break;}
}
if (flag) puts("boring"); else puts("non-boring");
}
return ;
}
【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 (正解暴力)的更多相关文章
- BZOJ 1818 线段树+扫描线
思路: 可以把题目转化成 给你一些沿坐标轴方向的线段 让你求交点个数 然后就线段树+扫描线 搞一搞 (线段不包含断点 最后+n 这种方式 比线段包含断点+各种特判要好写得多) //By SiriusR ...
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- 【POJ-2482】Stars in your window 线段树 + 扫描线
Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11706 Accepted: ...
- HDU 4419 Colourful Rectangle --离散化+线段树扫描线
题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...
- BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤
3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...
- BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞
看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...
- hdu 5091(线段树+扫描线)
上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...
- POJ1151+线段树+扫描线
/* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...
随机推荐
- php常见问题以及解决方法
在使用php的过程中,经常会出现一些问题,下面是我遇到的一些问题以及解决方法 1,乱码问题,中文乱码问题 原因是:编码方式不一样,有UTF-8,gbk-2312等编码方式,不同的编码方式导致浏览器在解 ...
- Html5 Egret游戏开发 成语大挑战(八)一般性二级页面处理
在游戏中,我们一般会有各种各样的二级页面,比如游戏暂停界面或者游戏结束界面,这些界面组成了对玩家交互主要手段,在游戏开发中,对于这些界面的coding组织是非常有学问的,如果倒退到十年前,游戏开发的老 ...
- React Native开发技术周报1
(一).资讯 1.React Native 0.21版本发布,最新版本功能特点,修复的Bug可以看一下已翻译 重要:如果升级 Android 项目到这个版本一定要读! 我们简化了 Android 应用 ...
- 【转】CSS Sprites教程大全(使用方法、工具介绍)
什么是CSS Sprite CSS Sprite 又叫CSS精灵,是目前大型网站中经常运用的图片处理方式.它的原理很简单,将网站上零散的小图片(或图标)整合在一张大图上,再用CSS中“backgrou ...
- [MCSM] Slice Sampler
1. 引言 之前介绍的MCMC算法都具有一般性和通用性(这里指Metropolis-Hasting 算法),但也存在一些特殊的依赖于仿真分布特征的MCMC方法.在介绍这一类算法(指Gibbs samp ...
- 使用spring boot和thrift、zookeeper建立微服务
Spring cloud适应于云端服务,也适用于企业信息化SOA建设.spring boot也是restful微服务开发的利器.但对于内网服务,即服务与服务之间的调用,spring并没有去刻意封装,也 ...
- [BZOJ2730][HNOI2012]矿场搭建(求割点)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2730 分析: 如果坍塌的点不是割点,那没什么影响,主要考虑坍塌的点是割点的情况. 显然 ...
- CSS 栅格布局
bootstrap3.0教程之栅格系统原理(布局) http://www.jb51.net/css/152846.html [div+css]栅格化布局样式备用坑 http://www.0773lin ...
- Hibernate 的dialect 大全
RDBMS 方言 DB2 org.hibernate.dialect.DB2Dialect DB2 AS/400 org.hibernate.dialect.DB2400Dialect DB2 OS3 ...
- 1118ALTER TABLE tabname DISCARD TABLESPACE快速导入数据利用表空间
-- 快速导入数据如果你有.ibd文件的一个干净的备份,你可以按如下操作从被起源的地方恢复它到MySQL安装中:相当快速 1. 发出这个ALTER TABLE语句: 2. ALTER TABLE tb ...