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
T
T. The descriptions of the test cases follow: Each test case starts with an integer
n
n
n (
1
≤
n
≤
200000
1 ≤ n ≤ 200000
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
题意
(有
T
T
T组数据) 每组数据给出一个
n
n
n与一个长为
n
n
n的数列,其中每个数为小于109的非负整数。若这个数列中每个连续的子数列都包含有(至少)一个与该子数列中其它任何数都不同的数,则输出“non-boring”,否则输出“boring”。
思路
考虑一个数列是自身的子数列,显然在整个数列中至少要有一个与其它任何数都不同的数。于是问题就转化为分析这个数两边的子数列是否是“non-boring”数列(因为包含这个数的子数列必然是“non-boring”数列)。对于左边(右边)的数列,同样可以通过寻找是否有与其他任何数都不同的数来把这个数列分割为一个更小的数列。或者不存在这个数,则整个数列为“boring”数列。
考虑
n
n
n最大为
200000
200000
200000且有多组数据,每次直接遍历整个子数列必然时间复杂度爆炸,所以可以用一个pre[]数组来存储
a
[
i
]
a[i]
a[i]前面最近的与
a
[
i
]
a[i]
a[i]相同的数的位置,一个aft[]数组来存储
a
[
i
]
a[i]
a[i]后面最近的与
a
[
i
]
a[i]
a[i]相同的数的位置,这样可以把每次寻找的时间复杂度降到O(1)。
特别注意
经测试,这样依然会TLE,将每次查询子数列中是否存在与a[i]相同的数的方式由从一端开始遍历改为从两端同时遍历就顺利A掉了这一题
AC版本代码
#include<map>
#include<set>
#include<stdio.h>
using namespace std;
int t,n;
int a[200010];
int pre[200010];
int aft[200010];
map<int,int>m;
map<int,int>::iterator it;
bool sear(int l,int r)
{
if(l>=r) return 1;
int i;
for(i=0;l+i<=r-i;i++)
{
if(pre[l+i]<l&&(aft[l+i]>r||aft[l+i]==0)) return sear(l,l+i-1)&&sear(l+i+1,r);
if(pre[r-i]<l&&(aft[r-i]>r||aft[r-i]==0)) return sear(l,r-i-1)&&sear(r-i+1,r);
}
return 0;
}
int main()
{
scanf("%d",&t);
while(t--)
{
bool flag=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
it=m.find(a[i]);
if(it==m.end())
m.insert(pair<int,int>(a[i],i));
else {
pre[i]=(*it).second;
aft[(*it).second]=i;
(*it).second=i;
}
}
if(flag) {printf("boring\n");m.clear();continue;}
flag=sear(1,n);
if(flag) printf("non-boring\n");else printf("boring\n");
for(int i=1;i<=n;i++) pre[i]=aft[i]=0;
m.clear();
}
return 0;
}
TLE版本代码
#include<map>
#include<set>
#include<stdio.h>
using namespace std;
int t,n;
int a[200010];
int pre[200010];
int aft[200010];
map<int,int>m;
map<int,int>::iterator it;
bool sear(int l,int r)
{
if(l>=r) return 1;
int i;
for(i=0;l+i<=r-i;i++)
{
if(pre[l+i]<l&&(aft[l+i]>r||aft[l+i]==0)) return sear(l,l+i-1)&&sear(l+i+1,r);
if(pre[r-i]<l&&(aft[r-i]>r||aft[r-i]==0)) return sear(l,r-i-1)&&sear(r-i+1,r);
}
return 0;
}
int main()
{
scanf("%d",&t);
while(t--)
{
bool flag=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
it=m.find(a[i]);
if(it==m.end())
m.insert(pair<int,int>(a[i],i));
else {
pre[i]=(*it).second;
aft[(*it).second]=i;
(*it).second=i;
}
}
if(flag) {printf("boring\n");m.clear();continue;}
flag=sear(1,n);
if(flag) printf("non-boring\n");else printf("boring\n");
for(int i=1;i<=n;i++) pre[i]=aft[i]=0;
m.clear();
}
return 0;
}