spoj705( 求不相同的子串个数)
来源:互联网 发布:安卓埋雷软件 编辑:程序博客网 时间:2024/06/05 21:58
题意:求串s的不同子串的个数
解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。
代码如下:
#include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>#include<string>#include<vector>#define N 50005#define inf 0x3f3f3f3f#define pi acos(-1.0)#define eps 10e-6using namespace std;char s[N];int r[N],wa[N],wb[N],wv[N],WS[N],sa[N];bool cmp(int *r,int a,int b,int l){ return r[a] == r[b] && r[a+l] == r[b+l];}void da(int n,int m){ int i, j, p, *x = wa, *y = wb, *t; for(i = 0; i < m; i++) WS[i] = 0; for(i = 0; i < n; i++) WS[ x[i] = r[i] ]++; for(i = 1; i < m; i++) WS[i] += WS[i-1]; for(i = n-1; i >= 0; i--) sa[ --WS[ x[i] ] ] = i; for(j = 1,p = 1; p < n; j*=2, m = p) { for(p = 0,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 < n; i++) wv[i] = x[ y[i] ]; for(i = 0; i < m; i++) WS[i] = 0; for(i = 0; i < n; i++) WS[ wv[i] ]++; for(i = 1; i < m; i++) WS[i] += WS[i-1]; for(i = n-1; i >= 0; i--) sa[ --WS[ wv[i] ] ] = y[i]; for(t = x,x = y,y = t,p = 1,x[ sa[0] ] = 0, i = 1; i < n; i++) x[ sa[i] ] = cmp(y,sa[i-1],sa[i],j) ? p-1 : p++; }}int rank[N],height[N];void calheight(int n){ int i,j,k = 0; for(i = 1; i <= n; i++) rank[ sa[i] ] = i; for(i = 0; i < n; height[ rank[i++] ] = k) for(k ? k-- : 0, j = sa[ rank[i] - 1 ]; r[i+k] == r[j+k]; k++);}void solve(int n){ int ans = 0; int i; // for(i = 1; i <= n; i++) cout<<sa[i]<<" ";cout<<endl;// for(i = 1; i <= n; i++) cout<<height[i]<<" ";cout<<endl; for(int i = 1; i <= n; i++) ans += (n-sa[i]-height[i]); printf("%d\n",ans);}int main(){ int t; scanf("%d",&t); while(t--) { int i; scanf("%s",s); int n = strlen(s); for(i = 0; i < n; i++) r[i] = s[i]+1; r[n] = 0; da(n+1,130); calheight(n); // for(i = 0; i <= n; i++) // cout<<height[i]<<" "; // cout<<endl; solve(n); } return 0;}
0 0
- spoj705( 求不相同的子串个数)
- 【后缀数组求不相同的子串的个数】spoj694 spoj705
- spoj694,spoj705 后缀数组/不相同的子串的个数 计算贡献
- Spoj694(Distinct Substrings)求字符串不相同的子串个数(后缀数组)
- SPOJ - DISUBSTR Distinct Substrings(后缀数组求不相同的子串个数)
- spoj 694 求一个字符串中不相同子串的个数
- SPOJ705不同的子串
- spoj 694 不相同的子串的个数
- [spoj694]不相同的子串的个数
- SPOJ 694,705(不相同的子串个数)
- 后缀数组(不相同子串的个数)spoj694
- 后缀数组(三)求给定字符串不相同的子串个数(hdu 4622 区间询问)
- SPOJ NSUBSTR 求每个对应的长度能产生的相同子串的最大个数
- SPOJ694 Distinct Substrings, 后缀数组, 不相同的子串的个数
- spoj 694 OR 705 不相同的子串的个数
- spoj 694 Distinct Substrings(不相同的子串的个数)
- SPOJ 694. Distinct Substrings (不相同的子串的个数--后缀数组)
- HDU 5769-Substring(后缀数组-不相同的子串的个数)
- 中国已成军事大国 可遏制日本重走军国主义老路
- URAL1917_Titan Ruins: Better late than killed_二分搜索
- CentOS 开发问题
- 找钱方式:递归,循环的解法
- 朝鲜半岛不再被关注 金正恩玩消失成功转移焦点
- spoj705( 求不相同的子串个数)
- 【Unity3D_Shader】流水Shader的名词查找和疑问
- MYSQL的explain工具简介
- matlab .m文件转换成exe可执行文件
- 判断是否存在一条直线穿过所有的线段
- 奥巴马对20国防长演讲:埃博拉疫情必须从源头根除
- 杭电2028
- poj3261(可重复k次的最长子串)
- 解放军新装备精品课目一上高原就出洋相 各种故障