首页 技术 正文
技术 2022年11月21日
0 收藏 810 点赞 4,505 浏览 1816 个字

原文链接https://www.cnblogs.com/zhouzhendong/p/CF235C.html

题目传送门 –  CF235C

题意

  给定一个字符串 $s$ ,多组询问,每组询问的形式为一个字符串 $T$ ,问 $S$ 有多少个子串与 $T$ 循环同构。(如果 $S$ 有多个相同子串都同构,则算多次)

  $|S|\leq 10^6,\sum |T|\leq 10^6$

题解

  以后坚决不念诗了!中午作死念诗,下午就被一个傻逼错误续了 3 个多钟头。

  做法:

  给 $S$ 建一个 SAM ,然后对于每一个 $T$ KMP 一下,找到最大循环节,在 SAM 上面走一走就可以了。

代码

#include <bits/stdc++.h>
#define right _47hurnf
using namespace std;
typedef long long LL;
const int N=1000005;
int n,m;
char s[N];
struct SAM{
int Next[26],fa,Max;
}t[N<<1];
int tax[N],id[N<<1],right[N<<1];
int size;
void init(){
memset(t,0,sizeof t);
size=1,t[0].Max=-1;
for (int i=0;i<26;i++)
t[0].Next[i]=1;
}
int extend(int p,int c){
if (t[p].Next[c]&&t[p].Max+1==t[t[p].Next[c]].Max)
return t[p].Next[c];
int np=++size,q,nq;
t[np].Max=t[p].Max+1;
for (;!t[p].Next[c];p=t[p].fa)
t[p].Next[c]=np;
q=t[p].Next[c];
if (t[p].Max+1==t[q].Max)
t[np].fa=q;
else {
nq=++size;
t[nq]=t[q],t[nq].Max=t[p].Max+1;
t[q].fa=t[np].fa=nq;
for (;t[p].Next[c]==q;p=t[p].fa)
t[p].Next[c]=nq;
}
return np;
}
int Fail[N];
int KMP(char s[],int n){
Fail[0]=Fail[1]=0;
for (int i=2;i<=n;i++){
int k=Fail[i-1];
while (k>0&&s[i]!=s[k+1])
k=Fail[k];
Fail[i]=k+(s[k+1]==s[i]?1:0);
}
int x=Fail[n];
while (x>0&&n%(n-x)!=0)
x=Fail[x];
return n-x;
}
int main(){
scanf("%s",s+1);
n=strlen(s+1);
init();
for (int i=1,p=1;i<=n;i++)
p=extend(p,s[i]-'a'),right[p]++;
for (int i=1;i<=size;i++)
tax[t[i].Max]++;
for (int i=1;i<=n;i++)
tax[i]+=tax[i-1];
for (int i=1;i<=size;i++)
id[tax[t[i].Max]--]=i;
for (int i=size;i>=1;i--)
right[t[id[i]].fa]+=right[id[i]];
scanf("%d",&m);
while (m--){
scanf("%s",s+1);
int len=strlen(s+1),r=KMP(s,len);
LL ans=0;
int p=1,Matched=0;
for (int i=1;i<=len;i++){
int c=s[i]-'a';
while (!t[p].Next[c])
p=t[p].fa,Matched=t[p].Max;
p=t[p].Next[c];
Matched++;
}
for (int i=1;i<=r;i++){
int c=s[i]-'a';
while (!t[p].Next[c])
p=t[p].fa,Matched=t[p].Max;
p=t[p].Next[c];
Matched++;
while (t[t[p].fa].Max>=len)
p=t[p].fa,Matched=t[p].Max;
if (Matched>=len)
ans+=right[p];
}
printf("%I64d\n",ans);
}
return 0;
}

  

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,996
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,510
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,353
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,137
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,770
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,848