要快速在一段子序列中判断一个元素是否只出现一次 , 我们可以预处理出每个元素左边和右边最近的相同元素的位置 , 这样就可以 O( 1 ) 判断.

考虑一段序列 [ l , r ] , 假如我们找到了序列中唯一元素的位置 p , 那我们只需检查 [ l , p - 1 ] & [ p + 1 , r ] 是否 non-boring 即可 .

如何检查 序列 [ l , r ] 呢 ? 假如从左往右或者从右往左找 , 最坏情况下是 O( n ) , 总时间复杂度会变成 O( n² ) ; 假如我们从两边往中间找 , 那最坏情况是唯一元素在中间 ,  单次是 O( n ) , 但是现在划分出来的递归处理的左右两部分都是原序列长度的一半 , 这样总时间复杂度就是 O( nlogn ) 了

------------------------------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>
 
#define rep( i , n ) for( int i = 0 ; i < n ; ++i )
#define clr( x , c ) memset( x , c , sizeof( x ) )
 
using namespace std;
 
const int maxn = 200000 + 5;
 
int seq[ maxn ] , L[ maxn ] , R[ maxn ] , n;
map< int , int > S;
 
#define UNIQUE( x ) ( L[ x ] < l && R[ x ] > r )
 
bool check( int l , int r ) {
if( l >= r ) return true;
int t[ 2 ] = { l , r };
for( int p = 0 ; t[ 0 ] <= t[ 1 ] ; ( p ^= 1 ) ? t[ 0 ]++ : t[ 1 ]-- )
if( UNIQUE( t[ p ] ) )
   return check( l , t[ p ] - 1  ) && check( t[ p ] + 1 , r );
return false;
}
 
int main() {
freopen( "test.in" , "r" , stdin );
int t;
cin >> t;
while( t-- ) {
scanf( "%d" , &n );
rep( i , n )
L[ i ] = -1 , R[ i ] = n;
S.clear();
rep( i , n ) {
   scanf( "%d" , seq + i );
   if( S.find( seq[ i ] ) != S.end() )
       L[ i ] = S[ seq[ i ] ];
   S[ seq[ i ] ] = i;
}
S.clear();
for( int i = n - 1 ; i >= 0 ; i-- ) {
   if( S.find( seq[ i ] ) != S.end() )
    R[ i ] = S[ seq[ i ] ];
   S[ seq[ i ] ] = i;
}
printf( check( 0 , n - 1 ) ? "non-boring\n" : "boring\n" );
}
return 0;
}

------------------------------------------------------------------------------------------------------

4059: [Cerc2012]Non-boring sequences

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 300  Solved: 105
[Submit][Status][Discuss]

Description

我们害怕把这道题题面搞得太无聊了,所以我们决定让这题超短。一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子序列里至少存在一个数字只出现一次。给定一个整数序列,请你判断它是不是不无聊的。

Input

第一行一个正整数T,表示有T组数据。每组数据第一行一个正整数n,表示序列的长度,1 <= n <= 200000。接下来一行n个不超过10^9的非负整数,表示这个序列。

Output

对于每组数据输出一行,输出"non-boring"表示这个序列不无聊,输出"boring"表示这个序列无聊。

Sample Input

4
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

non-boring
boring
non-boring
boring

HINT

Source

BZOJ 4059: [Cerc2012]Non-boring sequences ( )的更多相关文章

  1. BZOJ 4059 [Cerc2012]Non-boring sequences(启发式分治)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4059 [题目大意] 一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的 ...

  2. 【刷题】BZOJ 4059 [Cerc2012]Non-boring sequences

    Description 我们害怕把这道题题面搞得太无聊了,所以我们决定让这题超短.一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子序列里至少存在一个数字只出现一次.给定 ...

  3. BZOJ 4059: [Cerc2012]Non-boring sequences(启发式分治)

    传送门 解题思路 首先可以想到要预处理一个\(nxt_i\)和\(pre_i\),表示前后与当前位置权值相同的节点,那么这样可以迅速算出某个点在某段区间是否出现多次.然后这样的话就考虑分治,对于\([ ...

  4. 【BZOJ 4059】 (分治暴力|扫描线+线段树)

    4059: [Cerc2012]Non-boring sequences Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 632  Solved: 22 ...

  5. bzoj 4059:Non-boring sequences 分治

    题目: 我们害怕把这道题题面搞得太无聊了,所以我们决定让这题超短.一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子序列里至少存在一个数字只出现一次.给定一个整数序列,请 ...

  6. 【bzoj 4059】Non-boring sequences

    这题的重点不在于代码,而在于复杂度分析…… 首先我们肯定会写 $n^2$ 暴力,就是每次暴力扫 $[l,r]$ 区间,找到任意一个在此区间中只出现过一次的数.设其下标为 $mid$,显然在这个区间中任 ...

  7. BZOJ 4057: [Cerc2012]Kingdoms( 状压dp )

    状压dp.... 我已开始用递归结果就 TLE 了... 不科学啊...我dp基本上都是用递归的..我只好改成递推 , 刷表法 将全部公司用二进制表示 , 压成一个数 . 0 表示破产 , 1 表示没 ...

  8. BZOJ 4057: [Cerc2012]Kingdoms

    状压DP #include<cstdio> #include<cstring> using namespace std; int F[1200005],A[25][25],st ...

  9. 【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 (正解暴力)

    4059: [Cerc2012]Non-boring sequences Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 440  Solved: 16 ...

随机推荐

  1. Hidden String(深搜)

    Hidden String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) ...

  2. js正则表达式验证字符长度

    原理,就是把一个汉字替换为两个字母,来实现长度验证. //js正则验证字符长度 第一种:直接输出长度 alert('1sS#符'.replace(/[^\x00-\xff]/g, 'AA').leng ...

  3. Sql server 事务的两种用法

    事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位. 通过事务,SQL Server能将逻辑相关的一组操作绑定在一起,以便 ...

  4. packstack安装以及centos源配置注意事项

    On CentOS:安装分为四步: 1,$ sudo yum install -y centos-release-openstack-mitaka 2,$ sudo yum update -y 3,$ ...

  5. 【Linux命令】查找命令

    如果你想在当前目录下 查找"hello,world!"字符串,可以这样: grep -rn "hello,world!" *

  6. php定时自动执行 需启动第一次

    1 2 3 4 5 6 7 8 9 10 11 12 <? ignore_user_abort(); //即使Client断开(如关掉浏览器),PHP脚本也可以继续执行. set_time_li ...

  7. [转载]MySql常用命令总结

    原文:http://www.php100.com/html/webkaifa/database/Mysql/2009/0910/3288.html1:使用SHOW语句找出在服务器上当前存在什么数据库: ...

  8. android中使用DisplayMetrics获取屏幕参数

    --关于Density int android.graphics.Bitmap.getDensity(),返回bitmap-density(密度).默认的density就是当前display-dens ...

  9. tomcat简介之web.xml详解(转)

    http://blog.csdn.net/facepp/archive/2008/04/19/2306602.aspx 位于每个Web应用的WEB-INF路径下的web.xml文件被称为配置描述符,这 ...

  10. Nginx 开启 debug 日志的办法

    译序:一般来讲,Nginx 的错误日志级别是 error,作为 Nginx 用户来讲,你设置成 info 就足够用了.         但有时有些难以挖掘的 bug,需要看到更详细的 debug 级别 ...