SPOJ 694/705 后缀数组
来源:互联网 发布:xp添加网络打印机 url 编辑:程序博客网 时间:2024/06/03 01:53
思路:
论文题*n
Σn-i-ht[i]+1 就是结果 O(n)搞定~
//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 55555int cases,n,cntA[N],cntB[N],A[N],B[N],rk[N],sa[N],tsa[N],ht[N];char s[N];void SA(){ memset(cntA,0,sizeof(cntA)); for(int i=1;i<=n;i++)cntA[s[i]]++; for(int i=1;i<=256;i++)cntA[i]+=cntA[i-1]; for(int i=n;i;i--)sa[cntA[s[i]]--]=i; rk[sa[1]]=1; for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]); for(int l=1;rk[sa[n]]<n;l<<=1){ memset(cntA,0,sizeof(cntA)); memset(cntB,0,sizeof(cntB)); for(int i=1;i<=n;i++) cntA[A[i]=rk[i]]++, cntB[B[i]=i+l<=n?rk[i+l]:0]++; for(int i=1;i<=n;i++)cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1]; for(int i=n;i;i--)tsa[cntB[B[i]]--]=i; for(int i=n;i;i--)sa[cntA[A[tsa[i]]]--]=tsa[i]; rk[sa[1]]=1; for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(A[sa[i]]!=A[sa[i-1]]||B[sa[i]]!=B[sa[i-1]]); } for(int i=1,j=0;i<=n;i++){ j=j?j-1:0; while(s[i+j]==s[sa[rk[i]-1]+j])j++; ht[rk[i]]=j; }}int main(){ scanf("%d",&cases); while(cases--){ long long ans=0; scanf("%s",s+1),n=strlen(s+1),SA(); for(int i=1;i<=n;i++)ans+=n-i-ht[i]+1; printf("%lld\n",ans); }}
0 0
- spoj 694&&705 后缀数组
- SPOJ 694&705 后缀数组
- SPOJ 694/705 后缀数组
- spoj 694,705 后缀数组,后缀自动机
- SPOJ 694 后缀数组
- SPOJ 694(后缀数组)
- SPOJ 694(后缀数组)
- SPOJ 694、705 后缀数组:求不同子串
- spoj 694 & spoj 705 Distinct Substrings (不同字串的个数 后缀数组)
- SPOJ 694 求不同子串数 后缀数组
- SPOJ 694 Distinct Substrings(后缀数组)
- 【后缀数组】【spoj 694】Distinct Substrings
- SPOJ 694 DISUBSTR Distinct Substrings 后缀数组
- spoj 694 Distinct Substrings (后缀数组应用)
- spoj 694 Distinct Substrings(后缀数组)
- spoj 694 Distinct Substrings (后缀数组)
- SPOJ 694 Distinct Substrings 后缀数组 模板
- SPOJ 694 Distinct Substrings(后缀数组)
- 2301: [HAOI2011]Problem b
- python并发
- 函数指针基础
- <<UNIX环境高级编程>>之第四章理解
- 位运算
- SPOJ 694/705 后缀数组
- 安卓按键精灵手机助手(功能:安卓版抓抓、命令库、制作电脑UI界面)
- HDU3183- 贪心
- STL关联容器
- Kubernetes Scheduler源码分析
- 【读书笔记】《LATEX入门》第二章【未完】
- python的多线程运用Threading
- 面向对象总结
- AWS配置红杏的两种方法