2016多校联合训练4 F - Substring 后缀数组
Description
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
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
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.
#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 后缀数组的更多相关文章
- 2016多校联合训练1 D题GCD (ST表+二分)
暑假颓废了好久啊...重新开始写博客 题目大意:给定10w个数,10w个询问.每次询问一个区间[l,r],求出gcd(a[l],a[l+1],...,a[r])以及有多少个区间[l',r']满足gcd ...
- 2016多校联合训练contest4 1012Bubble Sort
Bubble Sort Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Tota ...
- 河南多校联合训练 F 不是匹配
描述 有N个人,N个活动, 每个人只会对2个或者3个活动感兴趣, 每个活动也只有两个人或者两个活动对它兴趣,每个人参加一个 感兴趣的活动需要一天 ,且当天该活动被参加时,其他的人不能参加 如果 ...
- 2016多校联合训练1 B题Chess (博弈论 SG函数)
题目大意:一个n(n<=1000)行,20列的棋盘上有一些棋子,两个人下棋,每回合可以把任意一个棋子向右移动到这一行的离这个棋子最近的空格上(注意这里不一定是移动最后一个棋子),不能移动到棋盘外 ...
- HDU6318-2018ACM暑假多校联合训练2-1010-Swaps and Inversions-树状数组
本题题意是,给你一个长度为n的序列,使用最少的操作把序列转换为从小到大的顺序,并输出操作数*min(x,y) 实质上是算出该序列中有多少逆序对,有归并排序和树状数组两种算法,由于数据之间的差值有点大, ...
- hdu_1403_Longest Common Substring(后缀数组的应用)
题目链接:hdu_1403_Longest Common Substring 题意: 给你两个字符串,然你找最长的公共子串 题解: 后缀数组的经典应用,要找两个字符串的公共子串,那么就相当于找两个串的 ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- HDU 5769 Substring 后缀数组
Substring Problem Description ?? is practicing his program skill, and now he is given a string, he h ...
- hdu 5769 Substring 后缀数组 + KMP
http://acm.hdu.edu.cn/showproblem.php?pid=5769 题意:在S串中找出X串出现的不同子串的数目? 其中1 <= |S| < $10^5$ 官方题解 ...
随机推荐
- Python:基本语法1
I.Python中的转义符注意情况 如果'本身是一个字符,则可将其用" "括起来: 如果字符串内部既有',又有",则可用转义字符\,比如: 'I\'m\"OK\ ...
- dos命令行 指令
盘符: 例如想进入D盘 d: ../ 上一层目录 md 文件夹名 新建文件夹cd 文件夹名 进入到该目录cd.. 返回上一层目录cd\ 返回根目录 cd \windows 进入到当前盘Windows目 ...
- Matplotlib——第一章轻松画个图
首先安装matplotlib,使用pip install matplotlib.安装完成后在python的命令行敲入import matplotlib,如果没问题,说明安装成功可以开始画图了. 看好了 ...
- UVA - 11235 Frequent values
2007/2008 ACM International Collegiate Programming Contest University of Ulm Local Contest Problem F ...
- Redis 缓存过期(maxmemory) 配置/算法 详解
LRU(Least Recently Used) 最近最少使用算法是众多置换算法中的一种. Redis中有一个 maxmemory 概念,主要是为了将使用的内存限定在一个固定的大小.Redis 用到的 ...
- C#调用百度地图 api
转 http://blog.csdn.net/kkkkkxiaofei/article/details/8663377 这一篇,记录一下我调用的地图API实现的功能.下面介绍的都是一些片段的节选,不 ...
- 学习 opencv---(5) 创建Trackbar(活动条) &图像对比度,亮度值调整
学习如何在opencv 中用trackbar 函数创建和使用 轨迹条,以及图像对比度,亮度值的动态调整 一.OpenCV中轨迹条(Trackbar)的创建和使用 [1]创建轨迹条-----create ...
- [mark] 使用Sublime Text 2时如何将Tab配置为4个空格
在Mac OS X系统下,Sublime Text是一款比较赞的编辑器. 作为空格党的自觉,今天mark一下使用Sublime Text 2时如何将Tab配置为4个空格: 方法来自以下两个链接: ht ...
- qt添加cef库嵌入web [转]
qt cef嵌入web 原文http://blog.sina.com.cn/s/blog_9e59cf590102vnfc.html 最近项目需要,研究了下libcef库. Cef(Chromium ...
- Zookeeper开源客户端框架Curator简介
Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...