zoukankan      html  css  js  c++  java
  • HUST 1352 Repetitions of Substrings(字符串)

    Repetitions of Substrings

    Description

    The “repetitions” of a string S(whose length is n) is a maximum number “k” such that: 1) k is a factor of n 2) S[0..n/k-1] = S[p*(n/k)..(p+1)*(n/k)-1] for all that (1 <= p < n/k) for example: the repetitions of “aaaaaa”is 6. the repetitions of “abababab”is 4. the repetitions of “abcdef”is 1. Now, given a string S and a number K, please tell me how many substrings of S have repetitions NOT less than K.

    Input

    The input consists of several instances, each one for a single line. S K S is a string, K is a number. Check the Description for their meanings. S contains lowercase letters(ie 'a'..'z') only. 1 <= length of S <= 100000. 1 <= K <= length of S.

    Output

    For each instance, output the number of substring whose repetitions is NOT less than K.

    Sample Input

    abcabc 2
    acmac 3
    

    Sample Output

    1
    0

    先记录一下,完全不知道怎么回事。

    #include <stdio.h>  
    #include <string.h>  
    #include <iostream>  
    #include <algorithm>  
    #include <vector>  
    #include <queue>  
    #include <set>  
    #include <map>  
    #include <string>  
    #include <math.h>  
    #include <stdlib.h>  
    #include <time.h>  
    using namespace std;  
    const int maxn=300300;  
    int height[maxn],sa[maxn],rank[maxn],c[maxn],t1[maxn],t2[maxn];    
    void da(int *str,int n,int m)    
    {    
          int i,j,k,p,*x=t1,*y=t2;    
          for(i=0;i<m;i++)c[i]=0;    
          for(i=0;i<n;i++)c[x[i]=str[i]]++;    
          for(i=1;i<m;i++)c[i]+=c[i-1];    
          for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;    
          for(k=1;k<=n;k<<=1)    
          {    
             p=0;    
             for(i=n-k;i<n;i++)y[p++]=i;    
             for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;    
             for(i=0;i<m;i++)c[i]=0;    
             for(i=0;i<n;i++)c[x[y[i]]]++;    
             for(i=1;i<m;i++)c[i]+=c[i-1];    
             for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];    
             swap(x,y);    
             p=1;x[sa[0]]=0;    
             for(i=1;i<n;i++)    
             x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;    
             if(p>=n)break;    
             m=p;    
          }    
    }    
    void calheight(int *str,int n)    
    {    
          int i,j,k=0;    
          for(i=0;i<=n;i++)rank[sa[i]]=i;    
          for(i=0;i<n;i++)    
          {    
             if(k)k--;    
             j=sa[rank[i]-1];    
             while(str[i+k]==str[j+k])k++;    
             height[rank[i]]=k;    
          }    
             // printf("sa:");for(i=0;i<=n;i++)printf("%d ",sa[i]);puts("");    
             // printf("rank:");for(i=0;i<=n;i++)printf("%d ",rank[i]);puts("");    
             // printf("height:");for(i=0;i<=n;i++)printf("%d ",height[i]);puts("");    
            
    }    
    int str[maxn];    
    char ss[maxn];    
    int Log[maxn];    
    int best[23][maxn];    
    void init(int n)    
    {    
          int i,j;    
          Log[0]=-1;    
          for(i=1;i<=n;i++)    
             Log[i]=(i&(i-1))?Log[i-1]:Log[i-1]+1;    
          for(i=1;i<=n;i++)best[0][i]=height[i];    
          for(i=1;i<=Log[n];i++)    
             for(j=1;j<=n;j++)    
                best[i][j]=min(best[i-1][j],best[i-1][j+(1<<(i-1))]);    
    }    
    int lcp(int a,int b)    
    {    
          a=rank[a];    
          b=rank[b];    
          if(a>b)swap(a,b);    
          a++;    
          int t=Log[b-a+1];    
          return min(best[t][a],best[t][b-(1<<t)+1]);    
    }    
    int rep[maxn];  
    int main()  
    {  
          //freopen("data.in","r",stdin);  
          //freopen("data.out","w",stdout);  
          int i,j,k,m,n,p;  
          while(~scanf("%s%d",&ss,&k))  
          {  
             n=strlen(ss);  
               if(k==1)  
             {  
                printf("%lld
    ",(long long)n*(n+1)/2);  
                continue;  
             }  
             for(i=0;i<n;i++)str[i]=ss[i];  
             str[n]=0;  
             da(str,n+1,300);  
             calheight(str,n);  
             init(n);  
             for(i=0;i<=n;i++)rep[i]=1;  
             for(int L=1;L*k<=n;L++)  
             {  
                for(i=0;i<n;i+=L)  
                {  
                   int t=lcp(i,i+L);  
                   if(!t)continue;  
                   j=0;  
                   while(j<=i&&j<L&&str[i-j]==str[i-j+L])  
                   {  
                      if(t>=L&&lcp(i-j,i-j+L)>=(k-1)*L)  
                         rep[i-j]=max(rep[i-j],t/L+1);  
                      j++;t++;  
                   }  
                }  
             }  
             int ans=0;  
             for(i=0;i<=n;i++)if(rep[i]>=k)ans+=rep[i]-k+1;  
             printf("%d
    ",ans);  
          }  
          return 0;  
    }  
    View Code
  • 相关阅读:
    BIEE建模参考规范
    informatica 学习日记整理
    Web Service 的工作原理
    Oracle 时间差计算
    oracle基础知识
    Oracle 外连接和 (+)号的用法
    根据appId匹配项目名称
    vue技术分享-你可能不知道的7个秘密
    echarts3 迁徙图 迁入迁出
    ES6学习笔记
  • 原文地址:https://www.cnblogs.com/gpsx/p/5197914.html
Copyright © 2011-2022 走看看