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. 5.Android消息推送机制简单例子

    1.首先布局文件xml代码: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout x ...

  2. Leetcode 216. Combination Sum III

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  3. 【poj1739】 Tony's Tour

    http://poj.org/problem?id=1739 (题目链接) 题意 给出一个n*m的地图,有些是障碍.问从左下角走遍所有非障碍格子一次且仅一次最终到达右下角的路径方案数. Solutio ...

  4. JavaScript学习1

    http://blog.csdn.net/lilongsheng1125/article/details/8479391 数据类型 1.基础数据类型 数值型.字符串型.逻辑型.undefined.nu ...

  5. hibernate-cache

    hibernate缓存分:一级缓存.二级缓存.三级缓存 一级缓存:Session内的缓存 实例: /*一级缓存: * session内的缓存 * */ @Test public void test1( ...

  6. NFS网络文件共享

    NFS(Network File System) NFS在企业中的应用场景 企业集群架构中,NFS网络文件系统一般用来存储共享的视频.图片.附件等静态资源,一般把网站用户上传的文件都放到NFS共享里, ...

  7. JAVA语言规范-线程和锁章节之同步、等待和通知

    JAVA语言规范:线程和锁 1 同步 java编程语言提供了线程间通信的多种机制.这些方法中最基本的是同步化,此方法是使用监视器实现的.JAVA中每个对象与一个监视器相关联,一个线程可以加锁和解锁监视 ...

  8. 第二轮冲刺-Runner站立会议03

    今天做了什么:查看gridview与baseadapter适配器 明天准备做什么:继续gridview与baseadapter适配器 遇到的困难:暂无

  9. 在.net中使用GAC

    转自:http://blog.log4d.com/2011/01/gac/ GAC GAC是什么?是用来干嘛的?GAC的全称叫做全局程序集缓存,通俗的理解就是存放各种.net平台下面需要使用的dll的 ...

  10. zend studio汉化

    在help菜单中选择Install New Software,在 work with栏中添加上这样的地址 http://archive.eclipse.org/technology/babel/upd ...