题目链接:http://www.spoj.com/problems/DISUBSTR/en/

题意:给定一个字符串,求不相同的子串个数。

思路:直接根据09年oi论文<<后缀数组——出来字符串的有力工具>>的解法。

还有另一种思想:总数为n*(n-1)/2,height[i]是两个后缀的最长公共前缀,所以用总数-height[i]的和就是答案

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
#include<time.h>
#include<cmath>
using namespace std;
typedef long long int LL;
const int MAXN = + ;
int cmp(int *r, int a, int b, int l){
return r[a] == r[b] && r[a + l] == r[b + l];
}
int wa[MAXN], wb[MAXN], wv[MAXN], WS[MAXN];
void da(int *r, int *sa, int n, int m){
int i, j, p, *x = wa, *y = wb, *t;
for (i = ; i<m; i++) WS[i] = ;
for (i = ; i<n; i++) WS[x[i] = r[i]]++;
for (i = ; i<m; i++) WS[i] += WS[i - ];
for (i = n - ; i >= ; i--) sa[--WS[x[i]]] = i;
for (j = , p = ; p<n; j *= , m = p)
{
for (p = , i = n - j; i<n; i++) y[p++] = i;
for (i = ; i<n; i++) if (sa[i] >= j) y[p++] = sa[i] - j;
for (i = ; i<n; i++) wv[i] = x[y[i]];
for (i = ; i<m; i++) WS[i] = ;
for (i = ; i<n; i++) WS[wv[i]]++;
for (i = ; i<m; i++) WS[i] += WS[i - ];
for (i = n - ; i >= ; i--) sa[--WS[wv[i]]] = y[i];
for (t = x, x = y, y = t, p = , x[sa[]] = , i = ; i<n; i++)
x[sa[i]] = cmp(y, sa[i - ], sa[i], j) ? p - : p++;
}
return;
}
int Rank[MAXN], height[MAXN],sa[MAXN];
void calheight(int *r, int *sa, int n){
int i, j, k = ;
for (i = ; i <= n; i++) Rank[sa[i]] = i;
for (i = ; i < n; height[Rank[i++]] = k)
for (k ? k-- : , j = sa[Rank[i] - ]; r[i + k] == r[j + k]; k++);
return;
}
void solve(int n){
int ans = ;
for (int i = ; i <= n; i++){
ans += ((n - ) - sa[i] + - height[i]);
//(n-1)的原因,因为在最后加了一个原理字符串不存在的最小值
//0,所以字符串原始长度为n-1
}
printf("%d\n", ans);
}
int t, len,r[MAXN];
char str[MAXN];
int main(){
//#ifdef kirito
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
//#endif
// int start = clock();
scanf("%d", &t);
while (t--){
scanf("%s", str); len = strlen(str);
for (int i = ; i <= len; i++){
if (i == len){ r[i] = ; continue; } //字符串最后添加一个
//小于所以字符的值
r[i] = (int)str[i];
}
da(r, sa, len+, );
calheight(r, sa, len);
solve(len);
}
//#ifdef LOCAL_TIME
// cout << "[Finished in " << clock() - start << " ms]" << endl;
//#endif
return ;
}

SPOJ DISUBSTR 后缀数组的更多相关文章

  1. SPOJ DISUBSTR ——后缀数组

    [题目分析] 后缀数组模板题. 由于height数组存在RMQ的性质. 那么对于一个后缀,与前面相同的串总共有h[i]+sa[i]个.然后求和即可. [代码](模板来自Claris,这个板子太漂亮了) ...

  2. [spoj DISUBSTR]后缀数组统计不同子串个数

    题目链接:https://vjudge.net/contest/70655#problem/C 后缀数组的又一神奇应用.不同子串的个数,实际上就是所有后缀的不同前缀的个数. 考虑所有的后缀按照rank ...

  3. Distinct Substrings SPOJ - DISUBSTR 后缀数组

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  4. Distinct Substrings SPOJ - DISUBSTR(后缀数组水题)

    求不重复的子串个数 用所有的减去height就好了 推出来的... #include <iostream> #include <cstdio> #include <sst ...

  5. SPOJ SUBST1 后缀数组

    题目链接:http://www.spoj.com/problems/SUBST1/en/ 题意:给定一个字符串,求不相同的子串个数. 思路:直接根据09年oi论文<<后缀数组——出来字符串 ...

  6. SPOJ PHRASES 后缀数组

    题目链接:http://www.spoj.com/problems/PHRASES/en/ 题意:给定n个字符串,求一个最长的子串至少在每个串中的不重叠出现次数都不小于2.输出满足条件的最长子串长度 ...

  7. SPOJ REPEATS 后缀数组

    题目链接:http://www.spoj.com/problems/REPEATS/en/ 题意:首先定义了一个字符串的重复度.即一个字符串由一个子串重复k次构成.那么最大的k即是该字符串的重复度.现 ...

  8. SPOJ694 DISUBSTR --- 后缀数组 / 后缀自动机

    SPOJ694 DISUBSTR 题目描述: Given a string, we need to find the total number of its distinct substrings. ...

  9. Spoj-DISUBSTR - Distinct Substrings~New Distinct Substrings SPOJ - SUBST1~(后缀数组求解子串个数)

    Spoj-DISUBSTR - Distinct Substrings New Distinct Substrings SPOJ - SUBST1 我是根据kuangbin的后缀数组专题来的 这两题题 ...

随机推荐

  1. 最牛逼android上的图表库MpChart(三) 条形图

    最牛逼android上的图表库MpChart三 条形图 BarChart条形图介绍 BarChart条形图实例 BarChart效果 最牛逼android上的图表库MpChart(三) 条形图 最近工 ...

  2. 【leetcode】Bitwise AND of Numbers Range(middle)

    Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...

  3. 【OpenCV】直方图

    今天写直方图,学了几个相关函数 1. mixChannels void mixChannels(const Mat* src, int nsrc, Mat* dst, int ndst, const ...

  4. August 14th, Week 34th Sunday, 2016

    To live is to function, that is all there is in living. 活着就要发挥作用,这就是生活的全部内容. I often joke that my dr ...

  5. 群内大神与你交流WEB经验 业内专家指点就职技巧

    就知道你是一个有理想要抱负的人,不会满足于做一个初级的前端开发工程师.在接下来的这个阶段,我们将走上前端开发的进阶之路,将自己的能力再往上拔高一个等级.同样,薪资也会往上升一个等级!但是,如果你是一个 ...

  6. 【转】字符集和字符编码(Charset & Encoding)

    相信大家一定碰到过,打开某个网页,却显示一堆像乱码,如"бЇЯАзЪСЯ"."�????????"?还记得HTTP中的Accept-Charset.Accept ...

  7. 4.3 map和multimap

    使用map multimap必须包含头文件map *:multimap 1)multimap定义 template<class Key,class Pred=less<Key>,cl ...

  8. UVA 10252

    按照字典序输出最长公共子序列 #include<time.h> #include <cstdio> #include <iostream> #include< ...

  9. hdu1014

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1014 //hdu1014 0ms #include<stdio.h> #include&l ...

  10. Mac OS

    defaults write com.apple.finder AppleShowAllFiles -bool true 此命令显示隐藏文件defaults write com.apple.finde ...