【SPOJ DISUBSTR】Distinct Substrings 后缀数组
来源:互联网 发布:access数据库编辑器 编辑:程序博客网 时间:2024/06/05 14:17
Given a string, we need to find the total number of its distinct substrings.
Input
T- number of test cases. T<=20;
Each test case consists of one string, whose length is <= 1000
Output
For each test case output one number saying the number of distinct substrings.
Example
Sample Input:
2CCCCCABABA
Sample Output:
59
Explanation for the testcase with string ABABA:
len=1 : A,B
len=2 : AB,BA
len=3 : ABA,BAB
len=4 : ABAB,BABA
len=5 : ABABA
Thus, total number of distinct substrings is 9.
SPOJ还有一个题是【SUBST1 - New Distinct Substrings】,一模一样,不过nlog^2n过不了。
计数问题,贡献是当前后缀生成的子串数目减去高度数组的大小,也就是重复的子串数目。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int SZ = 1000010;int lcp[SZ],sa[SZ],tmp[SZ],k = 1,n,rank[SZ];bool cmp_sa(int i,int j){ if(rank[i] != rank[j]) return rank[i] < rank[j]; else { int x = i + k <= n ? rank[i + k] : -1; int y = j + k <= n ? rank[j + k] : -1; return x < y; }}void get_sa(char s[]){ for(int i = 0;i <= n;i ++) { sa[i] = i; rank[i] = i == n ? -1 : s[i]; } for(k = 1;k <= n;k <<= 1) { sort(sa,sa + 1 + n,cmp_sa); tmp[sa[0]] = 0; for(int i = 1;i <= n;i ++) tmp[sa[i]] = tmp[sa[i - 1]] + (cmp_sa(sa[i - 1],sa[i]) ? 1 : 0); for(int i = 0;i <= n;i ++) rank[i] = tmp[i]; }}void get_lcp(char s[]){ int h = 0; lcp[0] = 0; for(int i = 0;i <= n;i ++) rank[sa[i]] = i; for(int i = 0;i < n;i ++) { int j = sa[rank[i] - 1]; // cout<<"sa:"<<i<<" "<<j<<endl; if(h) h --; while(i + h < n && j + h < n) { if(s[i + h] == s[j + h]) h ++; else break; } lcp[rank[i] - 1] = h; }}LL ask(){ LL ans = 0; for(int i = 1;i <= n;i ++) { ans += n - sa[i] - lcp[i];// cout<<n - sa[i] - lcp[i]<<endl; } return ans;}void init(){ memset(sa,0,sizeof(sa)); memset(lcp,0,sizeof(lcp)); memset(rank,0,sizeof(rank)); memset(tmp,0,sizeof(tmp));}char s[SZ];int main(){ int T; scanf("%d",&T); while(T --) { init(); scanf("%s",s); n = strlen(s); get_sa(s); get_lcp(s); /* for(int i = 0;i <= n;i ++) printf("%d ",lcp[i]); puts(""); for(int i = 0;i <= n;i ++) printf("%d ",sa[i]); puts("");*/ printf("%lld\n",ask()); } return 0;}/*2CCCCCABABA*/
0 0
- SPOJ 694 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 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【后缀数组】不相同的子串的个数
- SPOJ694--- DISUBSTR - Distinct Substrings(后缀数组)
- [SPOJ705]DISUBSTR - Distinct Substrings(后缀数组)
- SPOJ - DISUBSTR Distinct Substrings(后缀数组求不相同的子串个数)
- SPOJ DISUBSTR - Distinct Substrings(后缀数组[不相同的子串的个数])
- SPOJ Distinct Substrings 后缀数组
- POJ 1129 Channel Allocation DFS+四色定理
- nginx ngx_http_limit_req_module 简单防下CC攻击
- 数据结构之串
- Servlet的基本知识
- android多语言切换
- 【SPOJ DISUBSTR】Distinct Substrings 后缀数组
- html5标签总结
- 微信调用扫一扫的步骤(ASP实现方式)
- C语言:未包含头文件引起的奇怪错误
- React-Native Windows完全安装指南
- xtrabackup
- Android 高清加载巨图方案 拒绝压缩图片
- 005_Http之request获取客户端信息03-获取请求参数
- Bitmap图片缩放处理