Substring


Problem Description
?? is practicing his program skill, and now he is given a string, he has to calculate the total number of its distinct substrings. 
But ?? thinks that is too easy, he wants to make this problem more interesting. 
?? likes a character X very much, so he wants to know the number of distinct substrings which contains at least one X. 
However, ?? is unable to solve it, please help him.
 
Input
 
The first line of the input gives the number of test cases T;T test cases follow. 
Each test case is consist of 2 lines: 
First line is a character X, and second line is a string S. 
X is a lowercase letter, and S contains lowercase letters(‘a’-‘z’) only.

T<=30 
1<=|S|<=10^5 
The sum of |S| in all the test cases is no more than 700,000.

 
Output
 
For each test case, output one line containing “Case #x: y”(without quotes), where x is the test case number(starting from 1) and y is the answer you get for that case.
 
Sample Input
 
2
a
abc
b
bbb
 
Sample Output
 
Case #1: 3
Case #2: 3

Hint

In first case, all distinct substrings containing at least one a: a, ab, abc.
In second case, all distinct substrings containing at least one b: b, bb, bbb.

 
题意:
  给你一个字符c和一个字符串s
  问你 s的所有有多少个不同的子串是包含c的
题解:
  考虑后缀数组
  我们对S建立出SA,Height
  在sa中,我们想要知道当前sa[i] 的后缀中是否含有字符c,这个可以预处理呀
  处理后,假设对于当前sa[i],的最前一个字符c的位置存在设为pre[sa[i]],那么我们可以更新答案 n - sa[i]
  但题目要求得是不同子串,那么我们对于每一位sa[i],利用height数组去重就可以了,自己想想把
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 2e5+, M = 2e5+, mod = 1e9+, inf = 2e9; ///heght[i] 表示 Suffix(sa[i-1])和Suffix(sa[i]) 的最长公共前缀:
///rk[i] 表示 开头为i的后缀的等级:
///sa[i] 表示 排名为i的后缀 的开头位置: int *rk,r[N],sa[N],height[N],wa[N],wb[N],wm[N];
bool cmp(int *r,int a,int b,int l) {
return r[a] == r[b] && r[a+l] == r[b+l];
}
void SA(int *r,int *sa,int n,int m) {
int *x=wa,*y=wb,*t;
for(int i=;i<m;++i)wm[i]=;
for(int i=;i<n;++i)wm[x[i]=r[i]]++;
for(int i=;i<m;++i)wm[i]+=wm[i-];
for(int i=n-;i>=;--i)sa[--wm[x[i]]]=i;
for(int i=,j=,p=;p<n;j=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<m;++i)wm[i]=;
for(i=;i<n;++i)wm[x[y[i]]]++;
for(i=;i<m;++i)wm[i]+=wm[i-];
for(i=n-;i>=;--i)sa[--wm[x[y[i]]]]=y[i];
for(t=x,x=y,y=t,i=p=,x[sa[]]=;i<n;++i) {
x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
}
}
rk=x;
}
void Height(int *r,int *sa,int n) {
for(int i=,j=,k=;i<n;height[rk[i++]]=k)
for(k?--k:,j=sa[rk[i]-];r[i+k] == r[j+k];++k);
} int pre[N];
LL ans;
char ch[],s[N];
int main() {
int T,cas = ;
scanf("%d",&T);
while(T--) {
scanf("%s%s",ch,s);
int n = strlen(s);
for(int i = ; i < n; ++i) r[i] = s[i] - 'a' + ;
r[n] = ;
SA(r,sa,n+,);
Height(r,sa,n);
pre[n] = -;
for(int i = n-; i >= ; --i) {
if(ch[] == s[i]) pre[i] = i;
else pre[i] = pre[i+];
}
ans = ;
for(int i = ; i <= n; ++i) {
if(pre[sa[i]] == -) continue;
ans = ans + (n - pre[sa[i]]) - max(,height[i] - pre[sa[i]] + sa[i]);
}
printf("Case #%d: %I64d\n",cas++,ans);
}
return ;
}

HDU 5769 Substring 后缀数组的更多相关文章

  1. hdu 5769 Substring 后缀数组 + KMP

    http://acm.hdu.edu.cn/showproblem.php?pid=5769 题意:在S串中找出X串出现的不同子串的数目? 其中1 <= |S| < $10^5$ 官方题解 ...

  2. HDU 5679 Substring 后缀数组判重

    题意:求母串中有多少不同的包含x字符的子串 分析:(首先奉上FZU官方题解) 上面那个题就是SPOJ694 ,其实这两个题一样,原理每次从小到大扫后缀sa数组,加上新的当前后缀的若干前缀,再减去重复的 ...

  3. HDU 5769 Substring(后缀数组)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5769 [题目大意] 在一个串中求出包含字母的子串个数, 只要存在一个字符不相等的子串即可视为不同的 ...

  4. hdu 1403 Longest Common Substring 后缀数组 模板题

    题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...

  5. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  6. hdu_1403_Longest Common Substring(后缀数组的应用)

    题目链接:hdu_1403_Longest Common Substring 题意: 给你两个字符串,然你找最长的公共子串 题解: 后缀数组的经典应用,要找两个字符串的公共子串,那么就相当于找两个串的 ...

  7. HDU 6194【后缀数组】

    题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=6194] 题意: 给你一个长度不大于1e5的字符串,然后然你判断其子串严格出现k次的子串个数. 题解: ...

  8. POJ3693 Maximum repetition substring 后缀数组

    POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...

  9. 2016多校联合训练4 F - Substring 后缀数组

    Description ?? is practicing his program skill, and now he is given a string, he has to calculate th ...

随机推荐

  1. jenkins持续集成源码管理选项为None,构建失败找不到git.exe解决办法

    我的jenkins版本为Jenkins ver. 2.19.1 1.源码管理选项只有None的解决办法: 在插件管理中心,搜索对应的源码管理插件这里以git为例,搜索git plugin点击右下角的安 ...

  2. Thinking in java学习笔记之持有对象总结

  3. bzoj1441 MIN

    Description 给出n个数(A1…An)现求一组整数序列(X1…Xn)使得S=A1*X1+…An*Xn>0,且S的值最小 Input 第一行给出数字N,代表有N个数 下面一行给出N个数 ...

  4. 用类方法------>快速创建一个autorelease的对象,在封装的类方法内部

    在封装的类方法内部,也就是+ (id)personWithName:(NSString *)name andAge:(int)age内部: 创建了一个person对象,并且创建了一个person*类型 ...

  5. [Python] 学习资料汇总

    Python是一种面向对象的解释性的计算机程序设计语言,也是一种功能强大且完善的通用型语言,已经有十多年的发展历史,成熟且稳定.Python 具有脚本语言中最丰富和强大的类库,足以支持绝大多数日常应用 ...

  6. UI第十一节——UIActivityIndicatorView

    - (void)viewDidLoad {    [super viewDidLoad];        // 创建一个UIActivityIndicatorView,大小是固定的    UIActi ...

  7. UI第九节——UIStepper

    - (void)viewDidLoad {    [super viewDidLoad];        // 实例化UIStepper,大小是固定的    UIStepper *stepper = ...

  8. PHP通过ini_set()来设置显示错误信息和执行时间

    PHP的 ini_set函数是设置选项中的值,在执行函数后生效,脚本结束的时候,这个设置也失效.不是所有的选项都能被改函数设置的.具体那些值能够设置,可以查看手册中的列表. 就是能够设置php.ini ...

  9. Go - 数组 和 切片(array、slice)

    一.数组 与其他大多数语言类似,Go语言的数组也是一个元素类型相同的定长的序列. (1)数组的创建 数组有 3 种创建方式: 1) [length]Type 2) [length]Type{value ...

  10. 网址前面的icon

    shortcut icon和icon代码之间究竟有何区别呢.下面介绍一下   语句一:<link rel="shortcut icon" href="favicon ...