SPOJ694 New Distinct Substrings
New Distinct Substrings
题目大意
给定一个字符串,求本质不同的子串个数
题解
SA常见思想:每一个子串都是某个后缀的前缀
考虑每一个后缀的贡献,首先他拥有n - sa[i]个(我是用的模板中,sa[i]的大小是0....n-1)前缀,这些前缀有height[i]个跟sa[i-1]相同,要减去。剩下的部分不可能与sa[i-1]之前的想通了,不然sa[i]会排在sa[i-1]前面
还要注意本题的字符集是小写字母(鬼知道样例是什么东西)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <cmath>
void swap(int &a, int &b){int tmp = a;a = b, b = tmp;}
void swap(int* &a, int* &b){int *tmp = a;a = b;b = tmp;}
int max(int a, int b){return a > b ? a : b;}
int min(int a, int b){return a < b ? a : b;}
void read(int &x)
{
x = 0;char ch = getchar(), c = ch;
while(ch < '0' || ch > '9') c = ch, ch = getchar();
while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
if(c == '-') x = -x;
}
const int INF = 0x3f3f3f3f;
const int MAXN = 50000 + 10;
struct SuffixArray
{
int s[MAXN], sa[MAXN], rank[MAXN], height[MAXN];
int t[MAXN], t2[MAXN], c[MAXN];
int n;
void clear(){n = 0;memset(sa, 0, sizeof(sa));}
void build_sa(int m)
{
++ n;
int i,*x=t,*y=t2;
for(i=0;i<m;++i) c[i]=0;
for(i=0;i<n;++i) x[i]=s[i];
for(i=0;i<n;++i) c[x[i]]++;
for(i=1;i<m;++i) c[i]+=c[i-1];
for(i=n-1;i>=0;--i) sa[--c[x[i]]]=i;
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(i=n-k;i<n;++i) y[p++]=i;
for(i=0;i<n;++i) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=0;i<m;++i) c[i]=0;
for(i=0;i<n;++i) c[x[i]]++;
for(i=1;i<m;++i) c[i]+=c[i-1];
for(i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1;x[sa[0]]=0;
for(i=1;i<n;++i)
x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?p-1:p++;
if(p>=n) break;
m=p;
}
-- n;
}
void build_height()
{
int i,j,k=0;
for(i=1;i<=n;++i) rank[sa[i]]=i;
for(i=0;i<n;++i)
{
if(k) k--;
j=sa[rank[i]-1];
while(s[i+k]==s[j+k]) k++;
height[rank[i]]=k;
}
}
}A;
int t, ans;
char tmp[MAXN];
int main()
{
read(t);
for(;t;-- t)
{
ans = 0;
scanf("%s", tmp);
A.s[0] = tmp[0] - 'a' + 1;
for(A.n = 1;tmp[A.n];++ A.n) A.s[A.n] = tmp[A.n] - 'a' + 1;
A.s[A.n] = 0;
A.build_sa(30);
A.build_height();
//调试信息
/*for(int i = 1;i <= A.n;++ i)
printf("sa[%d]:%s\n", i, tmp + A.sa[i]);
for(int i = 1;i <= A.n;++ i)
printf("height[%d]:%d\n", i, A.height[i]); */
for(int i = 1;i <= A.n;++ i)
ans += A.n - A.sa[i] - A.height[i];
printf("%d\n", ans);
}
return 0;
}
SPOJ694 New Distinct Substrings的更多相关文章
- spoj694 DISUBSTR - Distinct Substrings
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- 【SPOJ694】Distinct Substrings (SA)
求不相同子串个数 该问题等价于求所有后缀间不相同前缀的个数..也就是对于每个后缀suffix(sa[i]),将贡献出n-sa[i]+1个,但同时,要减去那些重复的,即为height[i],故答案 ...
- Distinct Substrings(spoj694)(sam(后缀自动机)||sa(后缀数组))
Given a string, we need to find the total number of its distinct substrings. Input \(T-\) number of ...
- 后缀数组---New Distinct Substrings
Description Given a string, we need to find the total number of its distinct substrings. Input T- nu ...
- SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转
694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number o ...
- 后缀数组:SPOJ SUBST1 - New Distinct Substrings
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- DISUBSTR - Distinct Substrings
DISUBSTR - Distinct Substrings no tags Given a string, we need to find the total number of its dist ...
- 705. New Distinct Substrings spoj(后缀数组求所有不同子串)
705. New Distinct Substrings Problem code: SUBST1 Given a string, we need to find the total number o ...
- 【SPOJ】Distinct Substrings(后缀自动机)
[SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...
随机推荐
- Spring-Security (补充)
一.配置静态资源过滤 直接在xml中配置即可 <!-- 配置静态资源过滤 --> <security:http security="none" pattern=& ...
- Java-Idea-笔记:lombok、微信支付依赖
ylbtech-Java-Idea-笔记:lombok.微信支付依赖 1. idea-install-lombok返回顶部 1.0. P:问题描述Idea每打开一个类文件,类名就标红,不影响运行,但g ...
- npm ERR! missing script: dev 解决方案
运行命令npm run dev 出现 npm ERR! missing script: dev 的错误 这是因为vue 版本问题,使用 npm run serve 来运行项目
- OCP—051试题
FROM: http://blog.itpub.net/26736162/viewspace-1252569/?page=2 http://blog.csdn.net/elearnings/artic ...
- 2019 USP Try-outs 练习赛
// 好久没更博客了,最近打了很多场练习赛&校内PK赛,大概自闭忙于补题吧 // 9.26 周四练习赛 A. Kolkhozy 题意 有 n 个数 \(f[i]\) ,有 q 次询问(l, r ...
- Fedora25安装mariadb并设置权限
MariaDB版本10.1.21 Fedora版本25 1.Change root user sudo -i 2. dnf install -y mysql dnf install -y mariad ...
- 将数据写到kafka的topic
package test05 import java.util.Propertiesimport org.apache.kafka.clients.producer.{KafkaProducer, P ...
- 2019-8-31-C#-如何写出一个不能被其他程序集继承的抽象类
title author date CreateTime categories C# 如何写出一个不能被其他程序集继承的抽象类 lindexi 2019-08-31 16:55:58 +0800 20 ...
- (转)lua protobuffer的实现
转自: http://www.voidcn.com/article/p-vmuovdgn-bam.html (1)lua实现protobuf的简介 需要读者对google的protobuf有一定的了解 ...
- postman连接不了localhost问题解决
学习搭建服务器可用postman 连接不了localhost的端口 网上好多教程是这样连接 看完视频后我们是这样 找了大量资料都解决不了,什么版本,什么证书的都不好使,最简单的就是去掉http:// ...