zoukankan      html  css  js  c++  java
  • BZOJ4556 HEOI2016 字符串

    后缀数组。

    复习了后缀数组后发现这题真的很好写。

    我们只需要将c依次向前向后扩展,找落在[a,b]区间内的最大值,遍历过程中不断用height数组更新。

    复杂度就是后缀数组,比主席树的快多了。

    By:大奕哥

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cstdio>
     6 using namespace std;
     7 const int N=1e5+10;
     8 inline int read()
     9 {
    10     char ch;ch=getchar();int x=0;
    11     while(ch<'0'||ch>'9')ch=getchar();
    12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    13     return x;
    14 }
    15 int wv[N],wu[N],wa[N],wb[N],sa[N],rank[N],height[N],r[N];
    16 inline int cmp(int *r,int a,int b,int l)
    17 {
    18     return r[a]==r[b]&&r[a+l]==r[b+l];
    19 }
    20 void da(int *r,int *sa,int n,int m)
    21 {
    22     int i,j,p;int *x=wa,*y=wb;
    23     for(i=0;i<m;++i)wu[i]=0;
    24     for(i=0;i<n;++i)wu[x[i]=r[i]]++;
    25     for(i=1;i<m;++i)wu[i]+=wu[i-1];
    26     for(i=n-1;i>=0;--i)sa[--wu[x[i]]]=i;
    27     for(j=1,p=1;p<n;j<<=1,m=p)
    28     {
    29         for(p=0,i=n-j;i<n;++i)y[p++]=i;
    30         for(i=0;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;
    31         for(i=0;i<n;++i)wv[i]=x[y[i]];
    32         for(i=0;i<m;++i)wu[i]=0;
    33         for(i=0;i<n;++i)wu[wv[i]]++;
    34         for(i=1;i<m;++i)wu[i]+=wu[i-1];
    35         for(i=n-1;i>=0;--i)sa[--wu[wv[i]]]=y[i];
    36         for(swap(x,y),p=1,x[sa[0]]=0,i=1;i<n;++i)
    37         x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    38     }
    39     return;
    40 }
    41 void calcHeight(int *rank,int *sa,int n)
    42 {
    43     int i,j,k=0;
    44     for(i=1;i<=n;++i)rank[sa[i]]=i;
    45     for(i=0;i<n;height[rank[i++]]=k)
    46         for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];++k);
    47     return;
    48 }
    49 char s[N];
    50 void work(int a,int b,int c,int d,int n)
    51 {
    52     int len=0,tmp=N;
    53     if(c>=a&&c<=b)len=max(len,min(d-c+1,b-c+1));
    54     for(int i=rank[c-1];i>=2;--i)
    55     {
    56         tmp=min(tmp,height[i]);
    57         if(height[i]==0||tmp<=len)break;
    58         if(sa[i-1]>=a-1&&sa[i-1]<=b-1)
    59         {
    60             len=max(len,min(min(min(tmp,height[i]),b-sa[i-1]),d-c+1));
    61         }
    62     }
    63     tmp=N;
    64     for(int i=rank[c-1]+1;i<=n;++i)
    65     {
    66         tmp=min(tmp,height[i]);
    67         if(height[i]==0||tmp<=len)break;
    68         if(sa[i]>=a-1&&sa[i]<=b-1)
    69         {
    70             len=max(len,min(min(min(tmp,height[i]),b-sa[i]),d-c+1));
    71         }
    72     }
    73     printf("%d
    ",len);
    74 }
    75 int main()
    76 {
    77     int n,m,a,b,c,d;
    78     n=read();m=read();
    79     scanf("%s",s);
    80     int len=strlen(s);
    81     for(int i=0;i<len;++i)r[i]=s[i];r[len]=0;
    82     da(r,sa,len+1,216);calcHeight(rank,sa,len);
    83     for(int i=1;i<=m;++i)
    84     {
    85         a=read();b=read();c=read();d=read();
    86         work(a,b,c,d,len);
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    iOS 开发学习之 User Interface(2)UIWindow 视窗
    iOS 开发学习之 User Interface(1)APP 生命周期
    OC-学习Tips
    初识Objective-C
    Android代码报错:setContentView(R.layout.activity_main)
    解决Discuz! info: MySQL Query Error
    技术网站
    java调用机器上的shell脚本
    素材网、图片库
    database工具
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8215412.html
Copyright © 2011-2022 走看看