zoukankan      html  css  js  c++  java
  • [HDU]3518——Boring counting

    zhan.jiang.ou now faced a tough problem,his english teacher quan.hong.chun gives him a string,which consists with n lower case letter,he must figure out how many substrings appear at least twice,moreover,such apearances can not overlap each other.
    Take aaaa as an example.”a” apears four times,”aa” apears two times without overlaping.however,aaa can’t apear more than one time without overlaping.since we can get “aaa” from [0-2](The position of string begins with 0) and [1-3]. But the interval [0-2] and [1-3] overlaps each other.So “aaa” can not take into account.Therefore,the answer is 2(“a”,and “aa”).

    题目大意:求一个字符串的不重叠子串的个数。

    思路:我真是太辣鸡了,其实这个题就是后缀数组性质②的应用,只不过是求出每个长度的答案(性质详见我的后缀数组的基本使用技巧)!

    总结:后缀数组英语应用太灵活,多回顾反思!

     1 #include<map>
     2 #include<set>
     3 #include<list>
     4 #include<deque>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #include<vector>
     9 #include<cstdio>
    10 #include<complex>
    11 #include<cstring>
    12 #include<cstdlib>
    13 #include<iostream>
    14 #include<algorithm>
    15 #define LL long long
    16 #define db double
    17 #define RG register
    18 #define maxx 1001
    19 #define Inf 666666
    20 using namespace std;int tong[maxx];
    21 int sa[maxx],X[maxx],Y[maxx],rnk[maxx],height[maxx],num[maxx];char s[maxx];
    22 bool comp(int *r,int a,int b,int len){
    23   return r[a]==r[b]&&r[a+len]==r[b+len];
    24 }
    25 void build_sa(int len){
    26   int *x=X,*y=Y,*t,Max=maxx/2;
    27   memset(tong,0,sizeof(tong));
    28   for(int i=0;i<len;++i)
    29     tong[x[i]=num[i]]++;
    30   for(int i=1;i<=Max;++i)
    31     tong[i]+=tong[i-1];
    32   for(int i=len-1;i!=-1;i--)
    33     sa[--tong[x[i]]]=i;
    34   for(int j=1,p=1,i;p<len;j<<=1,Max=p){
    35     for(i=len-1,p=0;i>=len-j;--i)y[p++]=i;
    36     for(i=0;i<len;++i)
    37       if(sa[i]>=j)y[p++]=sa[i]-j;
    38     for(i=0;i<=Max;++i)
    39       tong[i]=0;
    40     for(i=0;i<len;++i)
    41       tong[x[y[i]]]++;
    42     for(i=1;i<Max;++i)
    43       tong[i]+=tong[i-1];
    44     for(i=len-1;i!=-1;i--)
    45       sa[--tong[x[y[i]]]]=y[i];
    46     for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<len;++i)
    47       x[sa[i]]=comp(y,sa[i],sa[i-1],j)?p-1:p++;
    48   }
    49 }int n;
    50 void geth(){
    51   int j,k=0;
    52   for(int i=1;i<=n;++i)
    53     rnk[sa[i]]=i;
    54   for(int i=0;i<n;height[rnk[i++]]=k)
    55     for(k?k--:0,j=sa[rnk[i]-1];num[i+k]==num[j+k];k++);
    56 }
    57 void ans(){LL ans=0;
    58   for(RG int len=1;len<=(n/2);++len){
    59     int Max=-Inf,Min=Inf;
    60       for(RG int i=1;i<=n;++i){
    61     if(height[i]<len){
    62       if(Max-Min>=len)ans++;
    63       Max=-Inf,Min=Inf;
    64     }
    65     Max=max(Max,sa[i]);
    66     Min=min(Min,sa[i]);
    67     if(i==n&&Max-Min>=len)ans++;
    68     }
    69   }
    70   printf("%lld
    ",ans);
    71 }
    72 int main(){
    73   while(scanf("%s",s)){
    74     n=strlen(s);
    75     if(n==1&&s[0]=='#')break;
    76     memset(rnk,0,sizeof(rnk));
    77     memset(height,0,sizeof(height));
    78     memset(sa,0,sizeof(sa));
    79     memset(X,0,sizeof(X));
    80     memset(Y,0,sizeof(Y));
    81     for(int i=0;i<n;++i)
    82       num[i]=s[i]-55;
    83     num[n]=0;
    84     build_sa(n+1);
    85     geth();
    86     ans();
    87   }
    88   return 0;
    89 }
  • 相关阅读:
    20年的Flash要退出舞台:当年哪个小游戏你最爱?
    一些实用但不为人知的Unix命令
    20145221 《Java程序设计》第九周学习总结
    20145221 《Java程序设计》实验报告四:Android开发基础
    20145221 《Java程序设计》实验报告三:敏捷开发与XP实践
    20145221 《Java程序设计》第八周学习总结
    Java实现:数据结构之排序
    20145221 《Java程序设计》第七周学习总结
    20145221 《Java程序设计》实验报告二:Java面向对象程序设计
    网络安全攻防学习平台
  • 原文地址:https://www.cnblogs.com/zzmmm/p/6947027.html
Copyright © 2011-2022 走看看