博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【刷题】SPOJ 705 SUBST1 - New Distinct Substrings
阅读量:5281 次
发布时间:2019-06-14

本文共 2425 字,大约阅读时间需要 8 分钟。

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 <= 50000

Output

For each test case output one number saying the number of distinct substrings.

Example

Input:

2

CCCCC

ABABA

Output:

5

9

Solution

后缀排序后

一个后缀 \(SA[i]\)\(n-SA[i]+1\) 个子串,但后缀 \(SA[i]\)\(SA[i-1]\)\(height[i]\) 个字符相同,那么就有 \(height[i]\) 个子串一样,减去就是了

#include
#define ui unsigned int#define ll long long#define db double#define ld long double#define ull unsigned long longconst int MAXN=50000+10;char s[MAXN];int T,n,m,SA[MAXN],rk[MAXN],cnt[MAXN],nxt[MAXN],height[MAXN];template
inline void read(T &x){ T data=0,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w;}template
inline void write(T x,char ch='\0'){ if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(ch!='\0')putchar(ch);}template
inline void chkmin(T &x,T y){x=(y
inline void chkmax(T &x,T y){x=(y>x?y:x);}template
inline T min(T x,T y){return x
inline T max(T x,T y){return x>y?x:y;}inline void GetSA(){ n=strlen(s+1),m=300; for(register int i=1;i<=n;++i)rk[i]=s[i]; for(register int i=1;i<=m;++i)cnt[i]=0; for(register int i=1;i<=n;++i)cnt[rk[i]]++; for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1]; for(register int i=n;i>=1;--i)SA[cnt[rk[i]]--]=i; for(register int k=1,ps;k<=n;k<<=1) { ps=0; for(register int i=n-k+1;i<=n;++i)nxt[++ps]=i; for(register int i=1;i<=n;++i) if(SA[i]>k)nxt[++ps]=SA[i]-k; for(register int i=1;i<=m;++i)cnt[i]=0; for(register int i=1;i<=n;++i)cnt[rk[i]]++; for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1]; for(register int i=n;i>=1;--i)SA[cnt[rk[nxt[i]]]--]=nxt[i]; std::swap(nxt,rk); rk[SA[1]]=1;ps=1; for(register int i=2;i<=n;rk[SA[i]]=ps,++i) if(nxt[SA[i]]!=nxt[SA[i-1]]||nxt[SA[i]+k]!=nxt[SA[i-1]+k])ps++; if(ps>=n)break; m=ps; } for(register int i=1,j,k=0;i<=n;height[rk[i++]]=k) for(k=k?k-1:k,j=SA[rk[i]-1];s[i+k]==s[j+k];++k);}inline int solve(){ int ans=0; for(register int i=1;i<=n;++i)ans+=n-SA[i]+1-height[i]; return ans;}int main(){ read(T); while(T--) { scanf("%s",s+1); GetSA(); write(solve(),'\n'); } return 0;}

转载于:https://www.cnblogs.com/hongyj/p/9074184.html

你可能感兴趣的文章
创业公司该不该被收购?(转)
查看>>
sqlserver 行转列、列转行[转]
查看>>
【IScroll深入学习】解决IScroll疑难杂症
查看>>
python 数据类型
查看>>
108-PHP类成员protected和private成员属性不能被查看数值
查看>>
ajax post data 获取不到数据,注意contentType
查看>>
css控制height充满浏览器视口
查看>>
Linux 系统目录结构
查看>>
查看CPU数量和核心数
查看>>
Android异步加载网络图片
查看>>
python学习之 - XML
查看>>
css问题小计
查看>>
Laravel学习笔记(三)数据库 数据库迁移
查看>>
ORACLE查看并修改最大连接数
查看>>
box-flex不均分问题
查看>>
Python--GIL 详解
查看>>
Oracle数据导入Mysql中
查看>>
BZOJ-4424 &&CodeForces-19E Fairy DP+dfs (Link-Cut-Tree可A)
查看>>
MongoDB学习笔记——聚合操作之group,distinct,count
查看>>
大道至简读后感(第四章)
查看>>