• [cerc2012][Gym100624D]20181013


    题意:一个序列,如果存在一个连续子序列,满足该子序列中没有只存在一次的序列,则原序列为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
    ");
    93         else printf("non-boring
    ");
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    程序员你写的代码,被爆出黑产了!
    .NET面试题系列之面向对象
    .NET必问的面试题系列之基本概念和语法
    xamarin开发android收集的一些工具
    C#爬虫使用代理刷csdn文章浏览量
    我们必须要知道的RESTful服务最佳实践
    MVP架构在xamarin android中的简单使用
    使用Xamarin实现跨平台移动应用开发(转载)
    博客园app for xamarin android一款简洁阅读的博客园android客户端
    vs2019企业版密钥
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/9809684.html
Copyright © 2020-2023  润新知