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. Java Web的web.xml文件作用及基本配置(转)

    其实web.xml就是asp.net的web.config一个道理. 说明: 一个web中完全可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的. web.xml文件是用来 ...

  2. Android Studio使用

    HelloWorld在虚拟机上正常运行,在红米1S上很抱歉,HelloWorld已停止运行.有时间解决. 在windows下感觉到Android Studio非常慢,急死人.

  3. 你所不了解的float(滥用float的怪异现象)

    float设计初衷就是为了实现文字环绕效果 原本页面流布局显示如上图所示,运用了float属性后就显示为如下图所示,这就是浮动的设计初衷 float的一些特性:包裹性.破坏性. 包裹的特性其实主要有三 ...

  4. POJ3249:Test for Job

    传送门 很简单的一道题,被卡了几次,死于答案非法统计. 题意是求图里的一条最长的路径满足起点的入度和终点的出度都是0,而且图是DAG. 既然是DAG求最长路,DP即可.搞出拓扑序,逆序DP,然后统计所 ...

  5. 介绍编译的less的两种IDE工具

    介绍编译的less的两种IDE工具 现在css预编译越来越普及了,著名的有less.sass.stylus等等等等.功能上基本上都是大同小异.这些个玩意儿主要表达的意思就是:"像编程一样的编 ...

  6. 双守护进程(不死service)-5.0系统以下

    上链接: http://files.cnblogs.com/files/andlp/DaemonProcess.zip 5.0以上  参考marsDaemon

  7. [Java] JSP笔记 - Java Bean

    一. Java Bean 是什么? Java Bean 其实就是一个符合特定规则的 Java Class.这些规则包括: 使用 public 声明的公用类 属性使用public 的get,set方法访 ...

  8. PHP常用代码汇总

    Get与Post //POST if(isset( $_POST['add_gift'] )) { $game=trim( $_POST['game'] ); } //GET if(isset( $_ ...

  9. [Java] Java执行Shell命令

    Methods ProcessBuilder.start() 和 Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来 ...

  10. 关于当传过来的值转换成string类型报错的问题

    有时候直接写 string str=request.param["str"].tostring;会报错,是因为接受到的值可能是空的 这个时候就可以这样写 string _actio ...