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.

 
思路:题目是给出一个串,求出这个串有多少个包含字符x的不同子串。首先考虑总的可能的方案数,对于每一个位置i,求出在它右边离她最近的字符x的位置p,那么这个位置贡献的答案就是n-p; 这样算出来的方案数显然会有重复,考虑去重。 我们对串求一遍后缀数组得到heigh数组,枚举heigh数组的每一个元素heigh[i],
即heigh[i] = LCP(sa[i-1],sa[i]);  如果在lcp这一段字符包含了x,且位置为pos,那么说明有lcp-pos个串重复了
 
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cmath>
#include <vector>
#include <bitset>
#define ll long long
#define rep(x,to) for(int x=0;x<(to);x++)
#define repn(x,to) for(int x=1;x<=(to);x++)
#define clr(x) memset(x,0,sizeof(x))
#define pli pair<ll, int>
#define MEMSET(x,v) memset(x,v,sizeof(x))
#define pll pair<ll,ll>
#define pb push_back
#define MP make_pair
using namespace std;
const int N = 5e5 + ;
int t1[N], t2[N], c[N]; bool cmp(int *r, int a, int b, int l) {
return r[a] == r[b] && r[a+l] == r[b+l];
}
void da(int str[], int sa[], int Rank[], int heigh[], int n, int m) {
n++;
int i, j, p, *x = t1, *y = t2;
for(i = ; i < m; ++i) c[i] = ;
for(i = ; i < n; ++i) c[ x[i] = str[i] ]++;
for(i = ; i < m; ++i) c[i] += c[i - ];
for(i = n - ; i >= ; --i) sa[ --c[ x[i] ] ] = i; for(j = ; j <= n; j <<= ) { p = ;
for(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) c[i] = ;
for(i = ; i < n; ++i) c[ x[ y[i] ] ]++;
for(i = ; i < m; ++i) c[i] += c[i - ];
for(i = n - ; i >=; --i) sa[ --c[ x[ y[i] ] ] ] = y[i];
swap(x, y);
p = ;
x[ sa[] ] = ;
for(i = ; i < n; ++i) x[ sa[i] ] = cmp(y, sa[i - ], sa[i], j) ? p - : p++;
if(p >= n) break;
m = p;
}
int k = ;
n--;
for(i = ; i <= n; ++i) Rank[ sa[i] ] = i;
for(i = ; i < n; ++i) {
if(k) k--;
j = sa[ Rank[i] - ];
while(str[i + k] == str[j + k]) k++;
heigh[ Rank[i] ] = k;
}
} int Rank[N], heigh[N];
char str[N];
int r[N];
int sa[N];
char X[];
int pre[N];
int pos[N];
int _ = ; void solve(int n) {
memset(pos, , sizeof pos);
int p = -;
ll sum = , num = ;
for(int i = n - ; i >= ; --i) {
if(str[i] == X[]) p = i;
pos[i] = p;
if(pos[i] != -) sum += (n - pos[i]);
}
//for(int i = 0; i < n; ++i) printf("%d ", pos[i]); for(int i = ; i <= n; ++i) { if(pos[ sa[i - ] ] == - || pos[ sa[i] ] == -) continue;
int c1 = pos[ sa[i - ] ] - sa[i - ] + ;
int c2 = pos[ sa[i] ] - sa[i] + ;
int h = heigh[i];
if(c1 > h || c2 > h) continue;
num += (h - c1 + );
}
printf("Case #%d: %I64d\n", _++, sum - num);
}
int main()
{
#ifdef LOCAL
freopen("in", "r", stdin);
#endif
int cas; scanf("%d", &cas);
while(cas --) {
scanf("%s%s", X, str);
int n = strlen(str);
for(int i = ; i < n; ++i) r[i] = str[i];
r[n] = ;
da(r, sa, Rank, heigh, n, ); solve(n);
// for(int i = 0; i < n; ++i) printf("%d ", Rank[i]); puts("");
// for(int i = 1; i <= n; ++i) printf("%d ", sa[i]); puts("");
// for(int i = 2; i <= n; ++i) printf("%d ", heigh[i]); puts("");
}
return ;
}

2016多校联合训练4 F - Substring 后缀数组的更多相关文章

  1. 2016多校联合训练1 D题GCD (ST表+二分)

    暑假颓废了好久啊...重新开始写博客 题目大意:给定10w个数,10w个询问.每次询问一个区间[l,r],求出gcd(a[l],a[l+1],...,a[r])以及有多少个区间[l',r']满足gcd ...

  2. 2016多校联合训练contest4 1012Bubble Sort

    Bubble Sort Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tota ...

  3. 河南多校联合训练 F 不是匹配

    描述  有N个人,N个活动, 每个人只会对2个或者3个活动感兴趣,  每个活动也只有两个人或者两个活动对它兴趣,每个人参加一个  感兴趣的活动需要一天 ,且当天该活动被参加时,其他的人不能参加  如果 ...

  4. 2016多校联合训练1 B题Chess (博弈论 SG函数)

    题目大意:一个n(n<=1000)行,20列的棋盘上有一些棋子,两个人下棋,每回合可以把任意一个棋子向右移动到这一行的离这个棋子最近的空格上(注意这里不一定是移动最后一个棋子),不能移动到棋盘外 ...

  5. HDU6318-2018ACM暑假多校联合训练2-1010-Swaps and Inversions-树状数组

    本题题意是,给你一个长度为n的序列,使用最少的操作把序列转换为从小到大的顺序,并输出操作数*min(x,y) 实质上是算出该序列中有多少逆序对,有归并排序和树状数组两种算法,由于数据之间的差值有点大, ...

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

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

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

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

  8. HDU 5769 Substring 后缀数组

    Substring Problem Description ?? is practicing his program skill, and now he is given a string, he h ...

  9. hdu 5769 Substring 后缀数组 + KMP

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

随机推荐

  1. Web获取客户端物理MAC地址(ocx插件)

    主要是通过ActiveX控件 从本地获取到MAC地址,传入到浏览器打开的网页中,再提交到服务器. 具体详解与步骤看文档中: 文件实例包下载 DotNetFX 文件夹附件文件:(可能安装时需用) dot ...

  2. Android中处理崩溃异常

    转自:http://my.eoe.cn/817027/archive/17997.html 大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不 ...

  3. BULK操作减少redo实验

    建表: create table sm_histable ( sm_id ), sm_subid ), service_type ), orgton ), orgnpi ), destton ), d ...

  4. c++中的继承与初始化

    1.在c++中构造函数.析构函数.=运算符.友元无法继承 2.const 成员.引用成员.类的对象成员没有默认构造函数时,需在类的构造函数初始化列表中对其进行初始化 3.基类无默认构造函数,派生类需在 ...

  5. PHP 图片上传工具类(支持多文件上传)

    ====================ImageUploadTool======================== <?php class ImageUploadTool { private ...

  6. ASP.NET MVC 5 使用autofac实现DI

    使用Nuget添加Autofac.MVC的引用 启动项设置 注册Controller 注册ModelBinder 注册相关的web abstraction 为View层启用属性注入 为Action F ...

  7. mysql character set exception

    问题: 插入数据时,报了这样一个错误:“_mysql_exceptions.Warning: Incorrect string value: ‘\xE6\xB5\x81\xE8\xA1\x8C…’ f ...

  8. Linux下安装流量监控工具iftop

    在Linux系统中,top命令可以查看系统资源包括内存,CPU占用信息,查看和探测网络状态可以使用netstat,nmap等工具,实时流量监控可以使用iftop,下面是在CentOS7系列系统上安装i ...

  9. appium for hybrid app 处理webview

    之前研究了一段时间的appium for native app 相应的总结如下:                                            appium测试环境搭建 :ht ...

  10. 在Ubuntu 14.04安装和使用Docker

    Docker是一个开源软件,它可以把一个Linux应用和它所依赖的一切(比如配置文件)都封装到一个容器.然而,Docker与虚拟机不同,它使用了沙箱机制,Docker容器不运行操作系统,它共享主机上的 ...