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 rst
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 10 9 . 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
wordnon-boring ' or
boring ‘
用map预处理出每个位置的左边和右边最近的相等元素,从而可以在O(1)的时间内判断任意区间内某元素是否唯一。
对于一个区间l..r,从两边开始找唯一的元素p,找见之后只需要判断l..p-1和p+1..r是否都满足即可。
预处理复杂度O(nlogn),分治复杂度也是O(nlogn),所以总的时间复杂度O(nlogn)。
注意由于有的数据T比较大而n比较小,用memset的话会超时。
#include<cstdio>
#include<cstring>
#include<map>
#define M(a) memset(a,0,sizeof(a))
using namespace std;
int left[200010],right[200010],a[200010];
bool ok(int l,int r)
{
if (l>=r) return 1;
int i,j,k,x,y,z;
for (i=l,j=r;i<=j;i++,j--)
{
if (left[i]<l&&right[i]>r) return ok(l,i-1)&&ok(i+1,r);
if (left[j]<l&&right[j]>r) return ok(l,j-1)&&ok(j+1,r);
}
return 0;
}
int main()
{
int i,j,k,m,n,p,q,x,y,z,T;
scanf("%d",&T);
while (T--)
{
map<int,int> mp;
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
{
if (mp.count(a[i]))
left[i]=mp[a[i]];
else
left[i]=-1;
mp[a[i]]=i;
}
mp.clear();
for (i=n;i>=1;i--)
{
if (mp.count(a[i]))
right[i]=mp[a[i]];
else
right[i]=n+1;
mp[a[i]]=i;
}
if (ok(1,n)) printf("non-boring\n");
else printf("boring\n");
}
}