题意:一个序列被称作是不无聊的,当且仅当,任意一个连续子区间,存在一个数字只出现了一次,问给定序列是否是不无聊的。
思路:每次找到一个只出现了一次的点,其位置的pos,那么继续分治[L,pos-1],[pos1+1,R];为了保证分治的复杂度,每次的复杂度应该是拆开后较小的哪个。
可以类比启发式合并。 所以我们应该从两头想中间找pos。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=200010;
int a[maxn],pre[maxn],lat[maxn]; map<int,int>mp;
bool check(int L,int R)
{
if(L>=R) return true;
int l=L,r=R;
rep(i,L,R){
if(i&1){
if(pre[l]<L&&lat[l]>R)
return check(L,l-1)&&check(l+1,R);
l++;
}
else {
if(pre[r]<L&&lat[r]>R)
return check(L,r-1)&&check(r+1,R);
r--;
}
}
return false;
}
int main()
{
int T,N;
scanf("%d",&T);
while(T--){
mp.clear();
scanf("%d",&N);
rep(i,1,N) scanf("%d",&a[i]);
rep(i,1,N){
lat[mp[a[i]]]=i;
pre[i]=mp[a[i]];
mp[a[i]]=i;
}
rep(i,1,N) lat[mp[a[i]]]=N+1;
if(check(1,N)) puts("non-boring");
else puts("boring");
}
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/4416801/blog/3468198