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");
}
}
本文来自博客园,作者:lei_yu,转载请注明原文链接:https://www.cnblogs.com/lytql/p/15224533.html