HDOJ 题目3518 Boring counting(后缀数组,求不重叠反复次数最少为2的子串种类数)
2017-07-03 11:14
435 查看
Boring counting
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2253 Accepted Submission(s): 924
Problem Description 035 now faced a tough problem,his english teacher 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”).
Input The input data consist with several test cases.The input ends with a line “#”.each test case contain a string consists with lower letter,the length n won’t exceed 1000(n <= 1000).
Output For each test case output an integer ans,which represent the answer for the test case.you’d better use int64 to avoid unnecessary trouble.
Sample Input
aaaa ababcabb aaaaaa #
Sample Output
2 3 3
Source 2010 ACM-ICPC Multi-University Training Contest(9)——Host by HNU
Recommend zhengfeng | We have carefully selected several similar problems for you: 3517
pid=3520]3520
3519 3521 3522Problem : 3518 ( Boring counting ) Judge Status : Accepted RunId : 14564325 Language : C++ Author : lwj1994 Code Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta
ac代码
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; int s[2002]; char str[2002]; int sa[2002],t1[2002],t2[2002],c[2002]; int Rank[2002],height[2002],ans; void build_sa(int s[],int n,int m) { int i,j,p,*x=t1,*y=t2; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[i]=s[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(j=1;j<=n;j<<=1) { p=0; for(i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 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-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; if(p>=n) break; m=p; } } void getHeight(int s[],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(s[i+k]==s[j+k]) k++; height[Rank[i]]=k; } } int judge(int n,int len) { int maxn=sa[0],minn=sa[0],ans=0; int i,j; for(i=1;i<=n;i++) { if(height[i]<len) { if(maxn-minn>=len) ans++; maxn=minn=sa[i]; } else { if(maxn<sa[i]) maxn=sa[i]; if(minn>sa[i]) minn=sa[i]; } } if(maxn-minn>=len) ans++; return ans; } int main() { int n; while(scanf("%s",str)!=EOF) { int i; if(strcmp(str,"#")==0) break; int len=strlen(str); for(i=0;i<len;i++) s[i]=str[i]-'a'+1; s[len]=0; build_sa(s,len+1,30); getHeight(s,len); int l=0,r=len; ans=0; for(i=1;i<=len/2;i++) { ans+=judge(len,i); } printf("%d\n",ans); } }
相关文章推荐
- HDOJ 题目3518 Boring counting(后缀数组,求不重叠重复次数最少为2的子串种类数)
- HDU 3518 Boring counting(后缀数组 所有不重叠字串出现两次以上的次数)
- HDOJ 题目4416 Good Article Good sentence(后缀数组求a串子串在b串中不出现的种类数)
- POJ 题目3261 Milk Patterns(后缀数组求最长重叠至少k次的子串长度)
- poj 3261 Milk Patterns 最长的出现最少k次的重复(可重叠)子串 后缀数组
- poj 3261 后缀数组 找反复出现k次的子串(子串能够重叠)
- hdoj 3518 Boring counting 【后缀数组】
- POJ 1743 Musical Theme 后缀数组 不可重叠最长反复子串
- POJ 3261 Milk Patterns(后缀数组 + 可重叠最长重复子串次数大于k)
- UVA 题目11512 - GATTACA(后缀数组求出现次数最多的子串及重复次数)
- 【后缀数组】 HDOJ 3518 Boring counting
- POJ3261 求指定出现次数的可重叠的最长重复子串(后缀数组)
- POJ 题目1743 Musical Theme(后缀数组,求一个串中最长不重叠重复子串)
- UVA 题目1223 - Editor(后缀数组求出现次数超过两次的最长子串的长度)
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)
- 【后缀数组求不可重叠最长重复子串】POJ 1743
- POJ 3261 Milk Patterns (离散化+后缀数组 可重叠k次最长重复子串)
- Repeats SPOJ (后缀数组,寻找一个重复次数最多的子串)
- HDU 3518 Boring counting[后缀数组]
- Poj 1743——Musical Theme——————【后缀数组,求最长不重叠重复子串长度】