CodeForces - 113B Petr# (后缀数组)
应该算是远古时期的一道题了吧,不过感觉挺经典的。
题意是给出三一个字符串s,a,b,求以a开头b结尾的本质不同的字符串数。
由于n不算大,用hash就可以搞,不过这道题是存在复杂度$O(nlogn)$的做法的。
由于要求本质不同,所以可以考虑使用后缀数组来不重复地枚举字符串。
首先用两个不同的其他字符将s,a,b拼起来求后缀数组,这样就可以知道任意两个后缀的lcp了。然后将s中所有b出现的末尾位置置1,求个后缀和suf。将s中所有后缀按名次从小到大存到一个vector里。对于s中的每个后缀,设其名次为x,a的长度为la,b的长度为lb,若$lcp(x,rnk[ia])=la$,则其对答案的贡献为$suf[sa[i]+max(lcp(x,vec[i-1]),la-1,lb-1)]$。其中la-1和lb-1是为了保证字符串长度比a和b都大,lcp(x,vec[i-1])是为了保证不重复枚举,相当于没有将s与a,b拼起来时的height[x]。特别地,当x=0时为0。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+;
char buf[N];
int s[N],sa[N],buf1[N],buf2[N],c[N],n,rnk[N],ht[N],ST[N][],Log[N],ia,ib,m,la,lb,suf[N];
void Sort(int* x,int* y,int m) {
for(int i=; i<m; ++i)c[i]=;
for(int i=; i<n; ++i)++c[x[i]];
for(int i=; i<m; ++i)c[i]+=c[i-];
for(int i=n-; i>=; --i)sa[--c[x[y[i]]]]=y[i];
}
void da(int* s,int n,int m=) {
int *x=buf1,*y=buf2;
s[n]=x[n]=y[n]=-;
for(int i=; i<n; ++i)x[i]=s[i],y[i]=i;
Sort(x,y,m);
for(int k=; k<n; k<<=) {
int p=;
for(int i=n-k; i<n; ++i)y[p++]=i;
for(int i=; i<n; ++i)if(sa[i]>=k)y[p++]=sa[i]-k;
Sort(x,y,m),p=,y[sa[]]=;
for(int i=; i<n; ++i)y[sa[i]]=x[sa[i-]]==x[sa[i]]&&x[sa[i-]+k]==x[sa[i]+k]?p-:p++;
if(p==n)break;
swap(x,y),m=p;
}
}
void getht() {
for(int i=; i<n; ++i)rnk[sa[i]]=i;
ht[]=;
for(int i=,k=; i<n; ++i) {
if(k)--k;
if(!rnk[i])continue;
for(; s[i+k]==s[sa[rnk[i]-]+k]; ++k);
ht[rnk[i]]=k;
}
}
void initST() {
for(int i=; i<n; ++i)ST[i][]=ht[i];
for(int j=; (<<j)<=n; ++j)
for(int i=; i+(<<j)-<n; ++i)
ST[i][j]=min(ST[i][j-],ST[i+(<<(j-))][j-]);
}
int lcp(int l,int r) {
if(l==r)return n-sa[l];
if(l>r)swap(l,r);
l++;
int k=Log[r-l+];
return min(ST[l][k],ST[r-(<<k)+][k]);
}
vector<int> vec;
int main() {
Log[]=-;
for(int i=; i<N; ++i)Log[i]=Log[i>>]+;
scanf("%s",buf),m=strlen(buf);
for(int i=; i<m; ++i)s[n++]=buf[i];
s[n++]='z'+,ia=n;
scanf("%s",buf),m=strlen(buf),la=m;
for(int i=; i<m; ++i)s[n++]=buf[i];
s[n++]='z'+,ib=n;
scanf("%s",buf),m=strlen(buf),lb=m;
for(int i=; i<m; ++i)s[n++]=buf[i];
s[n]=;
da(s,n),getht(),initST();
for(int i=; i<ia-; ++i)if(lcp(rnk[i],rnk[ib])==lb)suf[i+lb-]=;
for(int i=ia-; i>=; --i)suf[i]+=suf[i+];
for(int i=; i<ia-; ++i)vec.push_back(rnk[i]);
sort(vec.begin(),vec.end());
int ans=;
for(int i=; i<vec.size(); ++i) {
int x=vec[i];
if(lcp(x,rnk[ia])==la)ans+=suf[sa[x]+max(i?lcp(x,vec[i-]):,max(la-,lb-))];
}
printf("%d\n",ans);
return ;
}
CodeForces - 113B Petr# (后缀数组)的更多相关文章
- Liar CodeForces - 822E (dp,后缀数组)
大意: 给定串$s,t$, 给定整数$x$, 求判断$t$是否能划分为至多$x$段, 使这些段在$s$中按顺序,不交叉的出现. 设$dp_{i,j}$表示$s$匹配到$i$位, 划分了$j$段, 匹配 ...
- CodeForces 113B Petr#
题目链接:http://codeforces.com/problemset/problem/113/B 题目大意: 多组数据每组给定3个字符串T,Sbeg,Sed,求字符串T中有多少子串是以Sbeg开 ...
- Codeforces Good Bye 2015 D. New Year and Ancient Prophecy 后缀数组 树状数组 dp
D. New Year and Ancient Prophecy 题目连接: http://www.codeforces.com/contest/611/problem/C Description L ...
- 【Codeforces 113B】Petr#
Codeforces 113 B 题意:有一个母串\(S\)以及两个串\(S_{begin}\)和\(S_{end}\),问\(S\)中以\(S_{begin}\)为开头并且以\(S_{end}\)为 ...
- Codeforces 432D Prefixes and Suffixes (KMP、后缀数组)
题目链接: https://codeforces.com/contest/432/problem/D 题解: 做法一: KMP 显然next树上\(n\)的所有祖先都是答案,出现次数为next树子树大 ...
- Codeforces 1063F - String Journey(后缀数组+线段树+dp)
Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...
- Codeforces Round #246 (Div. 2) D. Prefixes and Suffixes(后缀数组orKMP)
D. Prefixes and Suffixes time limit per test 1 second memory limit per test 256 megabytes input stan ...
- Codeforces #123D: 后缀数组+单调栈
D. String You are given a string s. Each pair of numbers l and r that fulfill the condition 1 ≤ ...
- Codeforces VK Cup 2015 A.And Yet Another Bracket Sequence(后缀数组+平衡树+字符串)
这题做得比较复杂..应该有更好的做法 题目大意: 有一个括号序列,可以对其进行两种操作: · 向里面加一个括号,可以在开头,在结尾,在两个括号之间加. · 对当前括号序列进 ...
随机推荐
- 字符编码笔记:ASCII,Unicode 和 UTF-8(理解)
1.ASCII 码 美国制定的字符编码规则,对英语字符与二进制位之间的关系做了统一规定. 占一个字节,8 位,最多可表示 2^8 = 256 种状态(字符) 实际共有 128 个字符,只占用一个字节的 ...
- 如何下载spring sts
1.打开https://spring.io/ 2.翻到页面最底部点击tools 3.页面下滑点击Download STS4 Windows 64-bit
- cent7虚拟机切换root时出现"ABRT has detected ..."问题
今早打开虚拟机,在sudo -i的时候,发现出了这个问题: 于是我按照提示,执行abrt-cli list --since 1563382095后,结果如下: 大意就是内核出现了某CPU软死锁的问 ...
- python3中django-admin找不到core的解决方法
今天在测试django-admin startproject mysite时,出现以下问题: ImportError: No module named django.core 在执行此命令之前,我将d ...
- Date、DateFormat和Calendar类的简单认识
第三阶段 JAVA常见对象的学习 Date.DateFormat和Calendar类的简单认识 Date类 Date:表示特定的瞬间,精确到毫秒. (一) 构造方法: Date():根据当前的默认毫秒 ...
- 【转帖】龙芯3A3000处理器深度评测:和Intel、AMD差距巨大
龙芯3A3000处理器深度评测:和Intel.AMD差距巨大 https://www.eefocus.com/mcu-dsp/424623/r0 作者非计算机科班毕业 让我汗颜. 我计算机毕业都不知道 ...
- 2019HDU暑期多校训练-1004equation-方程求解
Description You are given two integers N,C and two integer sequences a and b of length N. The sequen ...
- 列表推导:python2和python3中作用域的问题
python2中: x = 'my love' dummy = [x for x in 'ABC'] print x 此时x打印为:'C' python3中: x = 'my love' dummy ...
- 第十三章 ZYNQ-MIZ701 TIMER定时器中断
上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每隔一秒中断一次,在中断函数里计数加1,通过串口打印输出. 本文所使用的开发板是Miz701 PC 开发环 ...
- 第十二章 ZYNQ-MIZ701 PL中断请求
本篇文章主要介绍外设(PL)产生的中断请求,在PS端进行处理. 在PL端通过按键产生中断,PS接受到之后点亮相应的LED. 本文所使用的开发板是Miz701 PC 开发环境版本:Vivado 20 ...