hdu3518 Boring Counting[后缀排序]

裸的统计不同的重复出现子串(不重叠)种数的题。多次使用后缀排序要注意小细节。y数组在重复使用时一定要清空,看那个line25 +k就明白了 ,cnt也要清空,为什么就不说了 
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
 5 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
 6 const int N=1000+7;
 7 char s[N];
 8 int n,m;
 9 ll ans;
10
11 int sa[N],rk[N],x[N],y[N],cnt[N],h[N],p;
12 inline void build(){
13     memset(cnt,0,sizeof cnt);memset(y,0,sizeof y);//
14     for(register int i=1;i<=n;++i)++cnt[x[i]=s[i]];
15     for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
16     for(register int i=n;i;--i)sa[cnt[x[i]]--]=i;
17     for(register int k=1;k<n;k<<=1,p=0){
18         for(register int i=n-k+1;i<=n;++i)y[++p]=i;
19         for(register int i=1;i<=n;++i)if(sa[i]>k)y[++p]=sa[i]-k;
20         for(register int i=1;i<=m;++i)cnt[i]=0;
21         for(register int i=1;i<=n;++i)++cnt[x[y[i]]];
22         for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
23         for(register int i=n;i;--i)sa[cnt[x[y[i]]]--]=y[i];
24         swap(x,y);x[sa[1]]=p=1;
25         for(register int i=2;i<=n;++i)x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p;
26         if(p==n)break; m=p;
27     }p=0;
28 //  for(register int i=1;i<=n;++i)printf("%d %d\n",i,x[i]);
29     for(register int i=1;i<=n;h[x[i]]=p,p?--p:1,++i)while(s[i+p]==s[sa[x[i]-1]+p]&&++p);
30 }
31
32 inline void search(int k){
33     int l=sa[1],r=sa[1];
34     for(register int i=2;i<=n;++i){
35         if(h[i]<k){r-l>=k?++ans:1;l=r=sa[i];}
36         MIN(l,sa[i]),MAX(r,sa[i]);
37     }
38     r-l>=k?++ans:1;
39 }
40
41 int main(){
42     while(~scanf("%s",s+1)){
43         if(s[1]==‘#‘)break;
44         n=strlen(s+1),m=127,ans=0,p=0,build();
45         for(register int i=1;i<=n/2;++i)search(i);
46         printf("%lld\n",ans);
47     }
48     return 0;
49 }



原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10340292.html

时间: 2024-11-12 08:20:46

hdu3518 Boring Counting[后缀排序]的相关文章

[HDU3518]Boring counting(后缀数组)

传送门 求出现超过1次的不重叠子串的个数 根据论文中的方法. 枚举子串的长度 k. 用 k 给 height 数组分组,每一组求解,看看当前组的位置最靠后的后缀和位置最靠前的后缀所差个数是否大于长度,大于的话 ans++. 分组思想需要认真体会一下. ——代码 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define N 1005 5 #define max(x, y) ((x) &

hdu 3518 Boring counting 后缀数组LCP

题目链接 题意:给定长度为n(n <= 1000)的只含小写字母的字符串,问字符串子串不重叠出现最少两次的不同子串个数; input: aaaa ababcabb aaaaaa # output 2 3 3 思路:套用后缀数组求解出sa数组和height数组,之后枚举后缀的公共前缀长度i,由于不能重叠,所以计数的是相邻height不满足LCP >= i的. 写写对后缀数组倍增算法的理解: 1.如果要sa数组对应的值也是1~n就需要在最后加上一个最小的且不出现的字符'#',里面y[]是利用sa数

HDU3518 Boring counting

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3182    Accepted Submission(s): 1319 Problem Description 035 now faced a tough problem,his english teacher gives him a string,which consists with

hdu 3518 Boring counting 后缀数组 height分组

题目链接 题意 对于给定的字符串,求有多少个 不重叠的子串 出现次数 \(\geq 2\). 思路 枚举子串长度 \(len\),以此作为分界值来对 \(height\) 值进行划分. 显然,对于每一组,组内子串具有一个长度为 \(len\) 的公共前缀. 至于是否重叠,只需判断 \(sa_{max}-sa_{min}\geq len\). 对于组间,显然它们的公共前缀互不相同,所以答案即为\(\sum_{len}\sum_{group}\) Code #include <bits/stdc++

后缀数组 --- HDU 3518 Boring counting

Boring counting Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,让你求出有多少个子串(无重叠)至少出现了两次. analyse: 后缀数组中height数组的运用,一般这个数组用得很少. 总体思路:分组统计的思想:将相同前缀的后缀分在一个组,然后对于1到len/2的每一个固定长度进行统计ans. 首先我们先求一遍后缀数组,并把height数组求出来.height数组代表的

hdu 3518 Boring counting(后缀数组)

Boring counting                                                                       Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Description 035 now faced a tough problem,his english teacher gives him

Boring counting HDU - 3518 (后缀数组)

Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要求子串之间不可以重合. 思路 对字符串后缀数组,然后枚举子串长度 \(len\),若某一段连续的 \(sa[i]\) 的 \(lcp \geq len\),那么说明这一段内存在一个长度为 \(lcp\) 的子串,而我们只需要其中的前 \(len\) 部分,接下来只要找出这个子串出现的最左和最右位置,

HDOJ 题目3518 Boring counting(后缀数组,求不重叠重复次数最少为2的子串种类数)

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,whic

BNUOJ 7629 Boring counting

Boring counting Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 351864-bit integer IO format: %I64d      Java class name: Main 035 now faced a tough problem,his english teacher gives him a string,which consis