【bzoj4059】【Cerc2012】【Non-boring sequences】【分治】

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
题解:
预处理出每个数的前一个位置和后一个位置.
对于一个数x它的位置是i,当l在[pre[i],i-1],r在[i+1,next[i]]之间时,[l,r]中x只出现过一次.
我们把每个x能产生贡献的区间放到二维平面上,显然是一个矩阵.
然后我们就可以扫描线+线段树处理.
这样会很慢.
正解是暴力.复杂度的证明非常神奇.
可以看这里:http://whx991201.is-programmer.com/posts/190036.html
代码:
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define N 210000
using namespace std;
map<int,int>point;
int pre[N],next[N],T,n,x,a[N];
bool check(int l,int r){
  int h=l,t=r;
  if (l>=r) return 1;
  for (int i=l;i<=r;i++)
    if (i&1){
      if (pre[h]<l&&next[h]>r) return check(l,h-1)&&check(h+1,r);
      h++;
	}
	else{
	  if (pre[t]<l&&next[t]>r) return check(l,t-1)&&check(t+1,r);
	  t--;
	}
  return 0;	
}
int main(){
  scanf("%d",&T);
  while (T--){
    point.clear();
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
       scanf("%d",&x);
       next[point[x]]=i;
       pre[i]=point[x];
       point[x]=i;a[i]=x;
    }
    for (int i=1;i<=n;i++) next[point[a[i]]]=n+1;
	if (check(1,n)) puts("non-boring");
    else puts("boring");
  }	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值