[SPOJ705]DISUBSTR - Distinct Substrings(后缀数组)
来源:互联网 发布:cf挂源码 编辑:程序博客网 时间:2024/06/08 15:46
题目描述
传送门
题解
每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数。如果所有的后缀按照suffix(sa[1]), suffix(sa[2]),suffix(sa[3]), …… ,suffix(sa[n]) 的顺序计算,不难发现,对于每一次新加进来的后缀suffix(sa[k]), 它将产生 n-sa[k]+1 个新的前缀。但是其中有 height[k] 个是和前面的字符串的前缀是相同的。所以 suffix(sa[k]) 将 贡献出 n-sa[k]+1-height[k] 个不同的子串。累加后便是原问题的答案。
代码
#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 50005int T,n,m,ans;char s[N];int *x,*y,X[N],Y[N],c[N],sa[N],height[N],rank[N];void clear(){ n=ans=0; memset(X,0,sizeof(X));memset(Y,0,sizeof(Y));memset(c,0,sizeof(c)); memset(sa,0,sizeof(sa));memset(height,0,sizeof(height));memset(rank,0,sizeof(rank));}void build_sa(){ m=200; x=X,y=Y; for (int i=0;i<m;++i) c[i]=0; for (int i=0;i<n;++i) ++c[x[i]=s[i]]; for (int i=0;i<m;++i) c[i]+=c[i-1]; for (int i=n-1;i>=0;--i) sa[--c[x[i]]]=i; for (int k=1;k<=n;k<<=1) { int p=0; for (int i=n-k;i<n;++i) y[p++]=i; for (int i=0;i<n;++i) if (sa[i]>=k) y[p++]=sa[i]-k; for (int i=0;i<m;++i) c[i]=0; for (int i=0;i<n;++i) ++c[x[y[i]]]; for (int i=0;i<m;++i) c[i]+=c[i-1]; for (int i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for (int i=1;i<n;++i) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&((sa[i-1]+k<n?y[sa[i-1]+k]:-1)==(sa[i]+k<n?y[sa[i]+k]:-1))?p-1:p++; if (p>n) break; m=p; }}void build_height(){ for (int i=0;i<n;++i) rank[sa[i]]=i; int k=0;height[0]=0; for (int i=0;i<n;++i) { if (!rank[i]) continue; if (k) --k; int j=sa[rank[i]-1]; while (i+k<n&&j+k<n&&s[i+k]==s[j+k]) ++k; height[rank[i]]=k; }}int main(){ scanf("%d\n",&T); while (T--) { clear(); gets(s);n=strlen(s); build_sa(); build_height(); for (int i=0;i<n;++i) ans+=n-sa[i]-height[i]; printf("%d\n",ans); }}
0 0
- [SPOJ705]DISUBSTR - Distinct Substrings(后缀数组)
- SPOJ DISUBSTR Distinct Substrings(后缀数组)
- SPOJ694&&SPOJ705:Distinct Substrings(后缀数组)
- SPOJ694&&SPOJ705:Distinct Substrings (后缀数组)
- 【SPOJ705】New Distinct Substrings 后缀数组
- [后缀数组]spoj694 Distinct Substrings/spoj705 New Distinct Substrings
- spoj 694 DISUBSTR - Distinct Substrings (后缀数组)
- SPOJ 694 DISUBSTR Distinct Substrings 后缀数组
- SPOJ694--- DISUBSTR - Distinct Substrings(后缀数组)
- [SPOJ DISUBSTR]Distinct Substrings(后缀数组)
- SPOJ DISUBSTR Distinct Substrings (后缀数组)
- 【SPOJ-DISUBSTR】Distinct Substrings【后缀数组】
- 【SPOJ DISUBSTR】Distinct Substrings 后缀数组
- SPOJ DISUBSTR Distinct Substrings 后缀数组子串个数
- SPOJ - DISUBSTR Distinct Substrings(后缀数组求不相同的子串个数)
- SPOJ 694 / SPOJ DISUBSTR Distinct Substrings【后缀数组】不相同的子串的个数
- SPOJ DISUBSTR - Distinct Substrings(后缀数组[不相同的子串的个数])
- Distinct Substrings后缀数组
- plsql编程 异常 EXCEPTION ROLLBACK
- 38-启动定时炸弹 alarm
- linux启动tomcat过程,像eclipse一样在控制台输出
- Kernal Panic - Not syncing : VFS: unable to mount root fs on unknown-block (0,0)
- 备忘一下,github撤销操作
- [SPOJ705]DISUBSTR - Distinct Substrings(后缀数组)
- openMP 并行编程 基础
- python中set()函数的用法
- 解决centos中tomcat8日志乱码问题
- 从零开始打造自己的框架 - 路由类
- R语言中常用的Data Frame数据框操作!
- mvc只控制器,模型,视图的搭建
- 报告显示:针对医疗行业的网络攻击预计将越来越多
- 谷歌浏览器崩溃的解决方案