zoukankan      html  css  js  c++  java
  • 后缀数组

    不可重叠最长重复子串 http://poj.org/problem?id=1743

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 class Suffix_Array {  ///后缀数组
     5     static const int MV=20010;///串长度
     6     int n,m,i,j,k,p,str[MV],sa[MV],height[MV],Rank[MV],wa[MV],wb[MV],wv[MV],ws[MV];///sa按字典序排序后后缀下标,rank后缀的排名,height排名相邻两个后缀的最长公共前缀
     7     bool cmp(int r[],int a,int b,int len) {
     8         return r[a]==r[b]&&r[a+len]==r[b+len];
     9     }
    10     void buildsa() {
    11         int *x=wa,*y=wb;
    12         for(i=0; i<m; i++) ws[i]=0;
    13         for(i=0; i<n; i++) ws[x[i]=str[i]]++;
    14         for(i=1; i<m; i++) ws[i]+=ws[i-1];
    15         for(i=n-1; i>=0; i--) sa[--ws[x[i]]]=i;
    16         for(j=p=1; p<n; j<<=1,m=p) {
    17             for(p=0,i=n-j; i<n; i++) y[p++]=i;
    18             for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
    19             for(i=0; i<m; i++) ws[i]=0;
    20             for(i=0; i<n; i++) ws[wv[i]=x[y[i]]]++;
    21             for(i=1; i<m; i++) ws[i]+=ws[i-1];
    22             for(i=n-1; i>=0; i--) sa[--ws[wv[i]]]=y[i];
    23             for(swap(x,y),x[sa[0]]=0,p=i=1; i<n; i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    24         }
    25     }
    26     void buildheight() {
    27         for(i=1; i<=n-1; i++) Rank[sa[i]]=i;
    28         for(i=k=0; i<n-1; height[Rank[i++]]=k)
    29             for(k?k--:0,j=sa[Rank[i]-1]; str[i+k]==str[j+k]; k++);
    30     }
    31 public:
    32     int getsa(int id) {
    33         return sa[id];
    34     }
    35     int getheight(int id) {
    36         return height[id];
    37     }
    38     int getrank(int id) {
    39         return Rank[id];
    40     }
    41     void build(int s[],int len,int cl) {///n为字符串长度加一,m为最大字符值加一
    42         n=len;
    43         m=cl;
    44         for(int i=0; i<=len; i++) str[i]=s[i];
    45         str[len]=0;
    46         buildsa();
    47         buildheight();
    48     }
    49 } gx;
    50 int n;
    51 bool judge(int len) {
    52     int up,down;
    53     up=down=gx.getsa(1);
    54     for(int i=2; i<=n; i++) {
    55         if(gx.getheight(i)<len) {
    56             up=down=gx.getsa(i);
    57         } else {
    58             up=max(up,gx.getsa(i));
    59             down=min(down,gx.getsa(i));
    60             if(up-down>len) return true;
    61         }
    62     }
    63     return false;
    64 }
    65 int Bins(int L,int R) {
    66     while(L<=R) {
    67         int mid=(L+R)>>1;
    68         if(judge(mid)) {
    69             L=mid+1;
    70         } else {
    71             R=mid-1;
    72         }
    73     }
    74     return R+1;
    75 }
    76 int a[20010];
    77 int main() {
    78     while(~scanf("%d",&n),n) {
    79         for(int i=0; i<n; i++) {
    80             scanf("%d",&a[i]);
    81         }
    82         for(int i=0; i<n-1; i++) {
    83             a[i]=a[i+1]-a[i]+88;
    84         }
    85         a[n-1]=0;
    86         gx.build(a,n,177);
    87         int ans=Bins(4,n);
    88         if(ans<5) ans=0;
    89         printf("%d
    ",ans);
    90     }
    91     return 0;
    92 }
    View Code

     可重叠的k 次最长重复子串 http://poj.org/problem?id=3261

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int M=2000100;  //可重叠的k 次最长重复子串
     5 class Suffix_Array {  ///后缀数组
     6     static const int MV=M;///串长度
     7     int n,m,i,j,k,p,str[MV],sa[MV],height[MV],Rank[MV],wa[MV],wb[MV],wv[MV],ws[MV];///sa按字典序排序后后缀下标,rank后缀的排名,height排名相邻两个后缀的最长公共前缀
     8     bool cmp(int r[],int a,int b,int len) {
     9         return r[a]==r[b]&&r[a+len]==r[b+len];
    10     }
    11     void buildsa() {
    12         int *x=wa,*y=wb;
    13         for(i=0; i<m; i++) ws[i]=0;
    14         for(i=0; i<n; i++) ws[x[i]=str[i]]++;
    15         for(i=1; i<m; i++) ws[i]+=ws[i-1];
    16         for(i=n-1; i>=0; i--) sa[--ws[x[i]]]=i;
    17         for(j=p=1; p<n; j<<=1,m=p) {
    18             for(p=0,i=n-j; i<n; i++) y[p++]=i;
    19             for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
    20             for(i=0; i<m; i++) ws[i]=0;
    21             for(i=0; i<n; i++) ws[wv[i]=x[y[i]]]++;
    22             for(i=1; i<m; i++) ws[i]+=ws[i-1];
    23             for(i=n-1; i>=0; i--) sa[--ws[wv[i]]]=y[i];
    24             for(swap(x,y),x[sa[0]]=0,p=i=1; i<n; i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    25         }
    26     }
    27     void buildheight() {
    28         for(i=1; i<=n-1; i++) Rank[sa[i]]=i;
    29         for(i=k=0; i<n-1; height[Rank[i++]]=k)
    30             for(k?k--:0,j=sa[Rank[i]-1]; str[i+k]==str[j+k]; k++);
    31     }
    32 public:
    33     int getsa(int id) {
    34         return sa[id];
    35     }
    36     int getheight(int id) {
    37         return height[id];
    38     }
    39     int getrank(int id) {
    40         return Rank[id];
    41     }
    42     void build(int s[],int len,int cl) {///n为字符串长度加一,m为最大字符值加一
    43         n=len;
    44         m=cl;
    45         for(int i=0; i<=len; i++) str[i]=s[i];
    46         str[len]=0;
    47         buildsa();
    48         buildheight();
    49     }
    50 } gx;
    51 int n,k;
    52 bool judge(int len) {
    53     int cnt;
    54     for(int i=2; i<=n; i++) {
    55         if(gx.getheight(i)<len) {
    56             cnt=1;
    57         } else {
    58             cnt++;
    59             if(cnt>=k) return true;
    60         }
    61     }
    62     return false;
    63 }
    64 int Bins(int L,int R) {
    65     while(L<=R) {
    66         int mid=(L+R)>>1;
    67         if(judge(mid)) {
    68             L=mid+1;
    69         } else {
    70             R=mid-1;
    71         }
    72     }
    73     return L-1;
    74 }
    75 int a[M];
    76 int main() {
    77     while(~scanf("%d%d",&n,&k)) {
    78         for(int i=0; i<n; i++) {
    79             scanf("%d",&a[i]);
    80             a[i]++;
    81         }
    82         gx.build(a,n+1,1000010);
    83         int ans=Bins(1,n);
    84         printf("%d
    ",ans);
    85     }
    86     return 0;
    87 }
    View Code

    不相同的子串的个数 http://www.spoj.com/problems/SUBST1/

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 typedef long long LL;
     6 class Suffix_Array {  ///后缀数组
     7     static const int MV=50010;///串长度
     8     int n,m,i,j,k,p,str[MV],sa[MV],height[MV],Rank[MV],wa[MV],wb[MV],wv[MV],ws[MV];///sa按字典序排序后后缀下标,rank后缀的排名,height排名相邻两个后缀的最长公共前缀
     9     bool cmp(int r[],int a,int b,int len) {
    10         return r[a]==r[b]&&r[a+len]==r[b+len];
    11     }
    12     void buildsa() {
    13         int *x=wa,*y=wb;
    14         for(i=0; i<m; i++) ws[i]=0;
    15         for(i=0; i<n; i++) ws[x[i]=str[i]]++;
    16         for(i=1; i<m; i++) ws[i]+=ws[i-1];
    17         for(i=n-1; i>=0; i--) sa[--ws[x[i]]]=i;
    18         for(j=p=1; p<n; j<<=1,m=p) {
    19             for(p=0,i=n-j; i<n; i++) y[p++]=i;
    20             for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
    21             for(i=0; i<m; i++) ws[i]=0;
    22             for(i=0; i<n; i++) ws[wv[i]=x[y[i]]]++;
    23             for(i=1; i<m; i++) ws[i]+=ws[i-1];
    24             for(i=n-1; i>=0; i--) sa[--ws[wv[i]]]=y[i];
    25             for(swap(x,y),x[sa[0]]=0,p=i=1; i<n; i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    26         }
    27     }
    28     void buildheight() {
    29         for(i=1; i<=n-1; i++) Rank[sa[i]]=i;
    30         for(i=k=0; i<n-1; height[Rank[i++]]=k)
    31             for(k?k--:0,j=sa[Rank[i]-1]; str[i+k]==str[j+k]; k++);
    32     }
    33 public:
    34     int getsa(int id) {
    35         return sa[id];
    36     }
    37     int getheight(int id) {
    38         return height[id];
    39     }
    40     int getrank(int id) {
    41         return Rank[id];
    42     }
    43     void build(char s[],int len,int cl) {///n为字符串长度加一,m为最大字符值加一
    44         n=len;
    45         m=cl;
    46         for(int i=0; i<=len; i++) str[i]=s[i];
    47         str[len]=0;
    48         buildsa();
    49         buildheight();
    50     }
    51 } gx;
    52 char a[50010];
    53 int main() {
    54     int t;
    55     while(~scanf("%d",&t)) {
    56         while(t--){
    57             scanf("%s",a);
    58             int n=strlen(a);
    59             gx.build(a,n+1,256);
    60             LL ans=0;
    61             for(int i=1;i<=n;i++){
    62                 ans+=n-gx.getsa(i)-gx.getheight(i);
    63             }
    64             printf("%lld
    ",ans);
    65         }
    66     }
    67     return 0;
    68 }
    View Code

    end

  • 相关阅读:
    图论1 Tarjan算法
    codevs1380 没有上司的舞会
    阿牛的EOF牛肉串
    codevs1105 过河
    HDU5340 Three Palindromes
    AndroidStudio中安装GsonFormat插件并根据json文件生成JavaBean
    Android中五种常用对话框的使用
    AndroidStudio中更新到最新版本后仍然提示:This version of the Android Support plugin for IntelliJ IDEA (or Android Studio) cannot o
    AndroidStudio中下载某版本gradle速度慢,从哪里高速下载指定版本gradle
    若依微服务版怎样修改Nacos中配置文件使Url不受权限认证跳过Token验证
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/4029402.html
Copyright © 2011-2022 走看看