【BZOJ 4059】 (分治暴力|掃描線+線段樹)

4059: [Cerc2012]Non-boring sequences

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 632  Solved: 227

Description

咱們懼怕把這道題題面搞得太無聊了,因此咱們決定讓這題超短。一個序列被稱爲是不無聊的,僅當它的每一個連續子序列存在一個獨一無二的數字,即每一個子序列裏至少存在一個數字只出現一次。給定一個整數序列,請你判斷它是否是不無聊的。php

Input

第一行一個正整數T,表示有T組數據。每組數據第一行一個正整數n,表示序列的長度,1 <= n <= 200000。接下來一行n個不超過10^9的非負整數,表示這個序列。node

Output

對於每組數據輸出一行,輸出"non-boring"表示這個序列不無聊,輸出"boring"表示這個序列無聊。ios

Sample Input

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

Sample Output

non-boring
boring
non-boring
boring

HINT

Source

鳴謝Tjzide

 

 

【分析】spa

  這題我是不會往掃描線方向想的。感受很神奇。code

  首先對於每一個a[i]求前一個同色的位置$last$和後一個的位置$next$,顯然左端點在[last+1,i]右端點在[i,next-1]的都是能夠的。xml

  那麼把左端點當成x,右端點當成y,區間就表示成了平面上的一個點,可行區間集就是一個矩形,最後看看n個矩形是否把上三角覆蓋。blog

  【這個把這題複雜化了,其實有更簡單的方法因此我沒打這個哦ip

 

  很容易想到暴力。get

  若是序列non-boring,一定有一個數值只出現了一次,找到他的位置i【可能有多個,先隨便找一個】,

  那麼區間跨越i的均可以的嘛,因此只需判斷[l,i-1]和[i+1,r]便可。

  就把區間分治了。

  可是時間複雜度???

  網上的神犇們說,從左右兩端向中間暴力枚舉,用$next$和$last$$O(1)$判斷便可。

  是nlogn的。

  由於:$T(n)=max{T(k)+T(n-k)+min(n,n-k)}=O(nlogn)$

  直觀證實:

  咱們考慮每一個對時間複雜度有貢獻的下標,它必定屬於兩段中比較小的那一段,因而。。

  每次每一個下標被算一次,它的所在塊就會縮小一倍,那麼顯然每一個下標的貢獻就是O(logn),它的總時間複雜度就是O(nlogn)。

  ORZORZ。。

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 200010
 8 
 9 struct node{int x,id;}t[Maxn];
10 bool cmp(node x,node y) {return x.x<y.x;}
11 int a[Maxn],nt[Maxn],lt[Maxn],ft[Maxn];
12 
13 bool ffind(int l,int r)
14 {
15     if(l>=r) return 1;
16     int t=-1;
17     for(int i=0;i<=r-l+1;i++)
18     {
19         if(l+i>r-i) break;
20         if(nt[l+i]>r&&lt[l+i]<l) {t=l+i;break;}
21         if(nt[r-i]>r&&lt[r-i]<l) {t=r-i;break;}
22     }
23     if(t==-1) return 0;
24     return ffind(l,t-1)&&ffind(t+1,r);
25 }
26 
27 int main()
28 {
29     int T;
30     scanf("%d",&T);
31     while(T--)
32     {
33         int n;
34         scanf("%d",&n);
35         for(int i=1;i<=n;i++)
36         {
37             scanf("%d",&t[i].x);t[i].id=i;
38         }
39         sort(t+1,t+1+n,cmp);
40         a[t[1].id]=1;int p=1;
41         for(int i=1;i<=n;i++)
42         {
43             if(t[i].x!=t[i-1].x) p++;
44             a[t[i].id]=p;
45         }
46         for(int i=1;i<=p;i++) ft[i]=n+1;
47         for(int i=n;i>=1;i--) nt[i]=ft[a[i]],ft[a[i]]=i;
48         for(int i=1;i<=p;i++) ft[i]=0;
49         for(int i=1;i<=n;i++) lt[i]=ft[a[i]],ft[a[i]]=i;
50         if(ffind(1,n)) printf("non-boring\n");
51         else printf("boring\n");
52     }
53     return 0;
54 }
View Code

 

2017-04-25 08:38:03

相關文章
相關標籤/搜索