UVA 1608 Non-boring sequences (递归分治)

题解:

小白上的题,如果一个序列的任意连续子序列中至少有一个只出现一次的元素,则称这个序列是不无聊的,输入一个n(n<=200000)个元素的序列A,判断是不是不无聊的

在整个序列中找一个只出现一次的元素,如果不存在,则这个序列不是不无聊的;如果找到一个只出现一次的元素A[P],那么只需检查A[1..P-1]和A[P+1…n]是否满足条件, 首先要解决的问题是如果快速的查找某个数字在序列中是否是唯一的数字。这里就是一个小的技巧,分别记录每个数字左边和右边最近的相同数字的坐标,就可以O(1)的判断任意一个连续子序列中,某个元素是否唯一。

如何进行查找呢?只是单纯的从左边和从右边开始查找,最坏的情况是位于最右边和最左边,这样最坏复杂度为O(N^2).但是我们同时从两边一起找,最坏的情况就是位于中间,这样的复杂度是O(nlgn)

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>

using namespace std;

const int MAX = 200010;

int N,T;
int a[MAX],l[MAX],r[MAX];

bool solve(int left, int right)
{
    if(left >= right)
        return true;
    for(int i = 0; i <= (right - left) / 2; ++i){
        if(l[left + i] < left && r[left + i] > right)
            return solve(left, left + i - 1) && solve(left + i + 1,right);
        if(l[right - i] < left && r[right - i] > right)
            return solve(left,right - i - 1) && solve(right - i + 1, right);
    }
    return false;
}

int main(void)
{
    //freopen("input.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        for(int i = 0; i < N; ++i)
            scanf("%d",&a[i]);
        map<int, int> M;
        for(int i = 0; i < N; ++i){
            if(!M.count(a[i])) l[i] = -1;
            else l[i] = M[a[i]];
            M[a[i]] = i;
        }
        M.clear();
        for(int i = N - 1; i >= 0; --i){
            if(!M.count(a[i])) r[i] = N;
            else r[i] = M[a[i]];
            M[a[i]] = i;
        }
        if(solve(0,N-1))
            puts("non-boring");
        else
            puts("boring");
    }
    return 0;
}

题目

Description

We were afraid of making this problem statement too boring, so we decided to keep it short. A sequence
is called non-boring if its every connected subsequence contains a unique element, i.e. an element such
that no other element of that subsequence has the same value.
Given a sequence of integers, decide whether it is non-boring.

Input

The first line of the input contains the number of test cases T. The descriptions of the test cases follow:
Each test case starts with an integer n (1 ≤ n ≤ 200000) denoting the length of the sequence. In
the next line the n elements of the sequence follow, separated with single spaces. The elements are
non-negative integers less than 109
.

Output

Print the answers to the test cases in the order in which they appear in the input. For each test case
print a single line containing the word ‘non-boring’ or ‘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

你可能感兴趣的:(UVA 1608 Non-boring sequences (递归分治))