题意
给你一个序列,问你这个序列是否满足任意一个连续子序列满足存在一个只出现一次的元素
思路
对于一个序列来说只要存在只出现一次的元素那么包含这个元素的左右序列都满足了,这时候分治判断不包含的情况下是否满足,对于一个连续子序列我们对于一个i求出这个元素前一次出现的位置和后一次出现的位置这样就能O(1)判断这个元素是否在这个序列中只出现一次了。
#include <iostream>
#include <map>
using namespace std;
const int MAXN=222222;
int num[MAXN],pre[MAXN],next_[MAXN];
map<int,int> mp;
bool fg;
bool dfs(int l,int r)
{
if(l>=r) return true;
int l1=l,r1=r;
int mid;
int fg1=0;
while(l1<=r1)
{
if(pre[l1]<l&&next_[l1]>r)
{
fg1=1;
mid=l1;
break;
}
if(pre[r1]<l&&next_[r1]>r)
{
fg1=1;
mid=r1;
break;
}
l1++;r1--;
}
if(!fg1) return false;
return dfs(l,mid-1)&&dfs(mid+1,r);
}
int main()
{
int T;cin>>T;
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&num[i]);
mp.clear();
for(int i=1;i<=n;i++)
{
if(mp[num[i]])
{
pre[i]=mp[num[i]];
mp[num[i]]=i;
}
else
{
pre[i]=0;
mp[num[i]]=i;
}
}
mp.clear();
for(int i=n;i>=1;i--)
{
if(mp[num[i]])
{
next_[i]=mp[num[i]];
mp[num[i]]=i;
}
else
{
next_[i]=n+1;
mp[num[i]]=i;
}
}
if(dfs(1,n)) printf("non-boring\n");
else printf("boring\n");
}
return 0;
}