[cerc2012][Gym100624D]20181013
阿新 • • 發佈:2018-11-11
題意:一個序列,如果存在一個連續子序列,滿足該子序列中沒有隻存在一次的序列,則原序列為boring,否則non-boring
題解:
分治遞迴
對一個序列,如果找到了一個只出現一次的數位於a[x],則問題轉化為子序列a[1]...a[x-1]和a[x+1]..a[len]這兩個序列有沒有boring序列,故分治。
判斷a[x]是否是在這個數列中只出現一次:記錄左邊最近一次出現a[x]的位置l[x],右邊為r[x],若數列為a[L]...a[R],則l[x]<L&&r[x]>R
找a[x]:
從兩邊向中間找,最壞情況為每次從兩邊找到中間,T(n)=T(n/2)+O(n) --> O(nlogn)
從中間向兩邊找,最壞情況為每次從中間找到兩邊,T(n)=T(n-1)+O(n) --> O(n^2)
1 /*
2 從兩邊向中間找,最壞情況為每次從兩邊找到中間,T(n)=T(n/2)+O(n) --> O(nlogn)
3 從中間向兩邊找,最壞情況為每次從中間找到兩邊,T(n)=T(n-1)+O(n) --> O(n^2)
4 */
5
6 #include<cstdio>
7 #include<cstdlib>
8 #include<cstring>
9 #include<iostream>
10 #include<algorithm>
11 #include<cmath>
12 #include<queue>
13 #include<vector>
14 #include<ctime>
15 using namespace std;
16
17 const int N=200010;
18 int a[N],l[N],r[N],id[N];
19 struct node{
20 int d,id;
21 }p[N];
22
23 bool cmp(node x,node y){return x.d<y.d;}
24
25 bool find_one(int L,int R)
26 {
27 if(L>R) return 0;
28 int mid=(L+R)/2;
29 int t=0,x;
30 for(int i=0;;i++)
31 {
32 if(L+i<=R && l[L+i]<L && r[L+i]>R) return find_one(L,L+i-1) || find_one(L+i+1,R);
33 if(R-i>=L && l[R-i]<L && r[R-i]>R) return find_one(L,R-i-1) || find_one(R-i+1,R);
34 if(L+i>R && R-i<L) break;
35 }
36 /*
37 //從中間向兩邊找 tle
38 while(mid+t<=R || mid-t>=L)
39 {
40 if(mid+t<=R)
41 {
42 x=mid+t;
43 if(l[x]<L && r[x]>R) return find_one(L,x-1) || find_one(x+1,R);
44 }
45 if(mid-t>=L)
46 {
47 x=mid-t;
48 if(l[x]<L && r[x]>R) return find_one(L,x-1) || find_one(x+1,R);
49 }
50 t++;
51 }
52 */
53 return 1;
54
55 }
56
57 int main()
58 {
59 //freopen("a.in","r",stdin);
60 int n,T;
61 scanf("%d",&T);
62 while(T--)
63 {
64 scanf("%d",&n);
65
66 for(int i=1;i<=n;i++)
67 {
68 scanf("%d",&a[i]);
69 p[i].d=a[i];
70 p[i].id=i;
71 }
72 sort(p+1,p+1+n,cmp);
73 int pre=-1,num=0;
74 for(int i=1;i<=n;i++)
75 {
76 if(p[i].d!=pre) num++;
77 pre=p[i].d;
78 a[p[i].id]=num;
79 }
80 memset(id,0,sizeof(id));
81 for(int i=1;i<=n;i++)
82 {
83 l[i]=id[a[i]];
84 id[a[i]]=i;
85 }
86 for(int i=1;i<=n;i++) id[a[i]]=n+1;
87 for(int i=n;i>=1;i--)
88 {
89 r[i]=id[a[i]];
90 id[a[i]]=i;
91 }
92 if(find_one(1,n)) printf("boring\n");
93 else printf("non-boring\n");
94 }
95 return 0;
96 }