# 【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 （正解暴力）

## 4059: [Cerc2012]Non-boring sequences

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 440  Solved: 160
[Submit][Status][Discuss]

4
5
1 2 3 4 5
5
1 1 1 1 1
5
1 2 3 2 1
5
1 1 2 1 1

non-boring
boring
non-boring
boring

## Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN 200010
int T,N,A[MAXN];
struct SegmentTreeNode{int minn,tag,l,r;}tree[MAXN<<2];
inline void Update(int now) {tree[now].minn=min(tree[now<<1].minn,tree[now<<1|1].minn);}
inline void PushDown(int now)
{
if (!tree[now].tag || tree[now].l==tree[now].r) return;
int tag=tree[now].tag; tree[now].tag=0;
tree[now<<1].minn+=tag; tree[now<<1].tag+=tag;
tree[now<<1|1].minn+=tag; tree[now<<1|1].tag+=tag;
}
void BuildTree(int now,int l,int r)
{
tree[now].l=l; tree[now].r=r; tree[now].minn=0; tree[now].tag=0;
if (l==r) return;
int mid=(l+r)>>1;
BuildTree(now<<1,l,mid);
BuildTree(now<<1|1,mid+1,r);
Update(now);
}
void Change(int now,int L,int R,int D)
{
PushDown(now);
int l=tree[now].l,r=tree[now].r;
if (L<=l && R>=r) {tree[now].tag+=D; tree[now].minn+=D; return;}
int mid=(l+r)>>1;
if (L<=mid) Change(now<<1,L,R,D);
if (R>mid) Change(now<<1|1,L,R,D);
Update(now);
}
int Query(int now,int L,int R)
{
PushDown(now);
int l=tree[now].l,r=tree[now].r;
if (L<=l && R>=r) return tree[now].minn;
int mid=(l+r)>>1,re=0x7fffffff;
if (L<=mid) re=min(re,Query(now<<1,L,R));
if (R>mid) re=min(re,Query(now<<1|1,L,R));
return re;
}
struct LineNode
{
int x,y1,y2,f;//y1>y2
LineNode (int x=0,int y1=0,int y2=0,int f=0)
: x(x),y1(y1),y2(y2),f(f) {}
bool operator < (const LineNode & A) const
{return x==A.x? y1<A.y1 : x<A.x;}
}Line[MAXN<<1];
int ls[MAXN<<1],tp,pre[MAXN],suf[MAXN],last[MAXN];
int main()
{
while (T--)
{
tp=0;
for (int i=1; i<=N; i++) ls[++tp]=A[i]=read();
sort(ls+1,ls+tp+1);
tp=unique(ls+1,ls+tp+1)-ls-1;
for (int i=1; i<=N; i++) A[i]=lower_bound(ls+1,ls+tp+1,A[i])-ls;
for (int i=1; i<=N; i++) pre[i]=suf[i]=last[i]=0;
for (int i=1; i<=N; i++)
{
if (!last[A[i]]) pre[i]=1;
else suf[last[A[i]]]=i-1,pre[i]=last[A[i]]+1;
last[A[i]]=i;
}
for (int i=1; i<=N; i++) if (!suf[i]) suf[i]=N;
//            for (int i=1; i<=N; i++) printf("%d %d %d \n",i,pre[i],suf[i]);
tp=0;
for (int i=1; i<=N; i++)
{
Line[++tp]=LineNode(pre[i],suf[i],i,1);
Line[++tp]=LineNode(i+1,suf[i],i,-1);
}
sort(Line+1,Line+tp+1);
//            for (int i=1; i<=tp; i++)
//                printf("%d %d %d %d\n",Line[i].x,Line[i].y2,Line[i].y1,Line[i].f);
BuildTree(1,1,N);
bool flag=0;
for (int X=1,i=1; X<=N; X++)
{
while (i<=tp && Line[i].x==X)
Change(1,Line[i].y2,Line[i].y1,Line[i].f),i++;
if (Query(1,X,N)==0) {flag=1; break;}
}
if (flag) puts("boring"); else puts("non-boring");
}
return 0;
}

posted @ 2016-08-24 17:38  DaD3zZ  阅读(590)  评论(0编辑  收藏  举报