UVA1608 不无聊的序列 Non-boring sequences

询问一个区间是否为一个排列,通常记录左右第一个在哪里出现。

从两遍往中间扫,发现某一个点满足第一个左右两边的数都不在当前区间范围内,那么他可以把区间分为两个部分且他自己满足条件,(因为要连续)继续递归求解即可。

由于两边同时计算,复杂度为\(O(nlogn)\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<set>
#include<iomanip>
#include<ctime>
#include<cstdlib>
#include<cmath>
using namespace std;
#define orz cout<<"lyakioi!!!!!!!!!!!!!!!!!"<<endl
inline int R(){int s=0,k=1;char c=getchar();while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}while(isdigit(c)){s=s*10+c-'0';c=getchar();}return s*k;}
int t,n,a[1000001],l[1000001],r[1000001];
map<int,int>m;
bool dfs(int now_l,int now_r)
{
	if(now_l>=now_r)return 1;
	for(int i=0;i<=(now_r-now_l+1)/2;i++)
	{
		int x=now_l+i,y=now_r-i;
		if(l[x]<now_l&&now_r<r[x])
		return dfs(now_l,x-1)&dfs(x+1,now_r);
		if(l[y]<now_l&&now_r<r[y])
		return dfs(now_l,y-1)&dfs(y+1,now_r);
	}
	return 0;
}
int main()
{
	t=R();
	while(t--)
	{
		m.clear();
		n=R();
		for(int i=1;i<=n;i++)
		l[i]=0,r[i]=1e9;
		for(int i=1;i<=n;i++)
		{
			a[i]=R();
			if(m.find(a[i])!=m.end())
			{
				int x=m[a[i]];
				r[x]=i;
				l[i]=x;
			}
			m[a[i]]=i;
		}
//		for(int i=1;i<=n;i++)cout<<l[i]<<" "<<r[i]<<endl;
		if(dfs(1,n))puts("non-boring");
		else puts("boring");
	}
}
posted @ 2021-09-03 18:44  lei_yu  阅读(25)  评论(0编辑  收藏  举报