SPOJ694&&SPOJ705:Distinct Substrings(后缀数组)
来源:互联网 发布:常用的音频编辑软件 编辑:程序博客网 时间:2024/06/06 18:34
Description
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:
2
CCCCC
ABABA
Sample Output:
5
9
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.
Hint
题意:要求不同子串的个数
一看到这道题,直觉就告诉我肯定是所有子串的数量减去所有height数组里的数值和,然后试着写了下就AC了,然后再仔细想了下,也确实如此,因为这些公共前缀都是多加了的
#include <iostream>#include <stdio.h>#include <string.h>#include <stack>#include <queue>#include <map>#include <set>#include <vector>#include <math.h>#include <bitset>#include <algorithm>#include <climits>using namespace std;#define LS 2*i#define RS 2*i+1#define UP(i,x,y) for(i=x;i<=y;i++)#define DOWN(i,x,y) for(i=x;i>=y;i--)#define MEM(a,x) memset(a,x,sizeof(a))#define W(a) while(a)#define gcd(a,b) __gcd(a,b)#define LL long long#define N 1005#define MOD 1000000007#define INF 0x3f3f3f3f#define EXP 1e-8int wa[N],wb[N],wsf[N],wv[N],sa[N];int rank[N],height[N],s[N],a[N];char str[N],str1[N],str2[N];//sa:字典序中排第i位的起始位置在str中第sa[i]//rank:就是str第i个位置的后缀是在字典序排第几//height:字典序排i和i-1的后缀的最长公共前缀int cmp(int *r,int a,int b,int k){ return r[a]==r[b]&&r[a+k]==r[b+k];}void getsa(int *r,int *sa,int n,int m)//n要包含末尾添加的0{ int i,j,p,*x=wa,*y=wb,*t; for(i=0; i<m; i++) wsf[i]=0; for(i=0; i<n; i++) wsf[x[i]=r[i]]++; for(i=1; i<m; i++) wsf[i]+=wsf[i-1]; for(i=n-1; i>=0; i--) sa[--wsf[x[i]]]=i; p=1; j=1; for(; 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++) wsf[i]=0; for(i=0; i<n; i++) wsf[wv[i]]++; for(i=1; i<m; i++) wsf[i]+=wsf[i-1]; for(i=n-1; i>=0; i--) sa[--wsf[wv[i]]]=y[i]; t=x; x=y; y=t; x[sa[0]]=0; for(p=1,i=1; i<n; i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++; }}void getheight(int *r,int n)//n不保存最后的0{ int i,j,k=0; for(i=1; i<=n; i++) rank[sa[i]]=i; for(i=0; i<n; i++) { if(k) k--; else k=0; j=sa[rank[i]-1]; while(r[i+k]==r[j+k]) k++; height[rank[i]]=k; }}int t,ans,n,m;int main(){ int i,j,k,len; scanf("%d",&t); W(t--) { scanf("%s",str); len = strlen(str); UP(i,0,len-1) s[i]=str[i]; s[len] = 0; getsa(s,sa,len+1,300); getheight(s,len); ans = (1+len)*len/2; UP(i,2,len) ans-=height[i]; printf("%d\n",ans); }}
0 0
- SPOJ694&&SPOJ705:Distinct Substrings(后缀数组)
- SPOJ694&&SPOJ705:Distinct Substrings (后缀数组)
- [后缀数组]spoj694 Distinct Substrings/spoj705 New Distinct Substrings
- spoj694 Distinct Substrings 后缀数组
- [SPOJ705]DISUBSTR - Distinct Substrings(后缀数组)
- 【SPOJ705】New Distinct Substrings 后缀数组
- SPOJ694--- DISUBSTR - Distinct Substrings(后缀数组)
- spoj694/705 Distinct Substrings - 后缀数组
- SPOJ694&SPOJ705(后缀数组)
- SPOJ694 Distinct Substrings, 后缀数组, 不相同的子串的个数
- Spoj694(Distinct Substrings)求字符串不相同的子串个数(后缀数组)
- spoj694 Distinct Substrings(后缀数组+统计不同子串的个数)
- Distinct Substrings后缀数组
- Distinct Substrings 后缀数组
- spoj694 Distinct Substrings
- spoj694 Distinct Substrings
- 【SPOJ705】New Distinct Substrings(BSOI3580)
- SPOJ Distinct Substrings 后缀数组
- GRE数学考试专业术语介绍
- MySQL命令备份数据库
- 自学Spring3+SpringMVC+Mybatis整合
- Web 开发中很实用的10个效果【源码下载】
- Jquery Validate 正则表达式实用验证代码大全
- SPOJ694&&SPOJ705:Distinct Substrings(后缀数组)
- HTML5学习之FileReader接口
- SAT填空解题题干规律
- Android JNI入门--jni头文件分析
- JS如何判断滚动条是否滚到底部
- svn 版本管理 相关
- 个人IOS技能树
- java设计模式:工厂模式
- kiki's game - HDU 2147 博弈论