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<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=50000+10;
char s[MAXN];
int T,n,m,SA[MAXN],rk[MAXN],cnt[MAXN],nxt[MAXN],height[MAXN];
template<typename T> 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<typename T> 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<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> 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;
}

最新文章

  1. Spring Batch学习笔记二
  2. 【OPENGL】第二篇 HELLO OPENGL(续)
  3. C#矩阵运算类库
  4. 2. Abstract Factory(抽象工厂)
  5. 自定义样式的select下拉框深入探索
  6. Linux 僵尸进程查杀
  7. 自动生成form Scripts
  8. RegisterWindowMessage介绍
  9. 使用Dom解析器,操作XML里面的信息
  10. 微信小程序简单入门1
  11. 201521123071 《JAVA程序设计》第二周学习总结
  12. 支持“WeShopDb”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库
  13. go-mysql: database/sql 接口适配
  14. 测试框架Unitest的运行原理,以及多个测试类中的执行顺序以及简化方法
  15. Qt控制流简析
  16. PHPStorm 配置命名空间
  17. 【BZOJ1188】分裂游戏(博弈论)
  18. Struts2漏洞拉响网站安全红色警报以及把Struts2更新为最新版本Struts2.3.15.1步骤
  19. 宝塔Linux面板安装Redis
  20. python爬虫----XPath

热门文章

  1. [数据结构]_[C/C++]_[链表的最佳创建方式]
  2. Java:xxx is not an enclosing class
  3. 解决美图看看不出现在“Open with”的子菜单中的问题
  4. Linux命令应用大词典-第30章 审计系统
  5. Unity操作小技巧
  6. HDU-1496(哈希表)
  7. 【循环控制器】-(针对中间部分要循环的场景,相当于loadrunner的action部分)
  8. Spark mlib的本地向量
  9. 一个简单的页面弹窗插件 jquery.pageMsgFrame.js
  10. [Clr via C#读书笔记]Cp15枚举和位标识