【SPOJ – SUBST1】New Distinct Substrings 后缀数组
2024-09-03 14:08:01
New Distinct Substrings
题意
给出T个字符串,问每个字符串有多少个不同的子串。
思路
字符串所有子串,可以看做由所有后缀的前缀组成。
按照后缀排序,遍历后缀,每次新增的前缀就是除了 与上一个后缀的所有公共前缀 之外的前缀。
答案就是用总数-重复的 即\(\frac{n(n+1)}{2}-\sum_{i=1}^{n}height[i]\)
代码
// #include <bits/stdc++.h>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int sa[N],cnt[N],pos[N],rk[N],oldrk[N],ht[N],n,m;
char str[N];
bool cmp(int a,int b,int k)
{
return oldrk[a]==oldrk[b]&&oldrk[a+k]==oldrk[b+k];
}
void getsa()
{
memset(cnt,0,sizeof(cnt));
m=122;
for(int i=1; i<=n; i++)
++cnt[rk[i]=str[i]];
for(int i=1; i<=m; i++)
cnt[i]+=cnt[i-1];
for(int i=n; i; i--)
sa[cnt[rk[i]]--]=i;
for(int k=1; k<=n; k<<=1)
{
int num=0;
for(int i=n-k+1; i<=n; i++)
pos[++num]=i;
for(int i=1; i<=n; i++)
{
if(sa[i]>k)
pos[++num]=sa[i]-k;
}
memset(cnt,0,sizeof(cnt));
for(int i=1; i<=n; i++)
++cnt[rk[i]];
for(int i=1; i<=m; i++)
cnt[i]+=cnt[i-1];
for(int i=n; i; i--)
sa[cnt[rk[pos[i]]]--]=pos[i];
memcpy(oldrk,rk,sizeof(rk));
num=0;
for(int i=1; i<=n; i++)
rk[sa[i]]=cmp(sa[i],sa[i-1],k)?num:++num;
if(num==n)
break;
m=num;
}
for(int i=1; i<=n; i++)
rk[sa[i]]=i;
int k=0;
for(int i=1; i<=n; i++)
{
if(k)
--k;
while(str[i+k]==str[sa[rk[i]-1]+k])
++k;
ht[rk[i]]=k;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",str+1);
n=strlen(str+1);
getsa();
ll sum=1LL*(n+1)*n/2;
for(int i=1; i<=n; i++)
sum-=ht[i];
printf("%lld\n",sum);
}
return 0;
}
最新文章
- sigemptyset,sigfillset,sigaddset,sigdelset,sigismember,sigprocmask,sigpendmask作用
- [HDU 5074] Hatsune Miku (动态规划)
- java synchronized使用
- Mysql中各种常见数据库存储引擎对比
- HTML重要标签及属性详解
- javaScript 验证码 倒计时60秒
- 操作系统内存管理之 内部碎片vs外部碎片
- 20175221 《Java程序设计》第8周学习总结
- java集合的三种遍历方式
- 报错:Column count doesn&#39;t match value count at row 1
- 分析器错误信息: 服务器标记不能包含 <;% ... %>; 构造
- Nexus搭建私服
- react-native学习之入门app
- [New learn] 网络基础-网络操作
- 1118 Birds in Forest
- Hive UDF开发 第一个例子
- log4j的各种类的配置
- TensorFlow框架(4)之CNN卷积神经网络详解
- 百度网络监控实战:NetRadar横空出世(上)
- 一款App的开发成本是多少?
热门文章
- Rank of Tetris 杭电 拓扑排序加并查集
- 详解 JDK8 新增的日期时间类
- .NET Core3.1总体预览和第一个Core程序的创建
- tensorflow1.0 数据队列FIFOQueue的使用
- Ubuntu初次使用的问题
- MySql --FIND_IN_SET() 函数 (转)
- PHP面向对象之重写与重载
- ajax发送时禁用按钮
- php://input和parse_str()使用
- mysql面试(1)