字符串

给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串?

分析

参照自为风月马前卒Candy?的题解。

广义后缀自动机不就是把很多串的SAM建到了一个SAM上,建每个串的时候都从root开始(last=root)就行了........

广义后缀自动机是Trie树的后缀自动机,可以解决多主串问题

这样的在线构造算法复杂度为O(G(T)),G(T)为Trie树上所有叶子节点深度和,发现G(T)<=所有主串总长度

对于这题,首先我们要知道几个定理

  1. 节点i表示的本质不同的字符串可以由len[i]−len[fa[i]]得到
  2. 一个串的子串 等价于 一个串所有前缀的所有后缀

这样子串就转换为求一个串的前缀的所有后缀的问题

前缀可以枚举,问题转换为求一个字符串的各个后缀在其他字符串中出现了多少次

这样我们可以把广义后缀自动机建出来,然后暴力沿着parent边跑,这样可以枚举出所有后缀

同时为了不重复枚举,我们需要记录下每个后缀是否已经被枚举过了

这样最坏情况下复杂度为O(L^3/2),发生在n=L的时候(均值不等式啊)

这样我们就可以知道一个状态出现的次数是否>=K,接下来我们只要统计出这个状态出现的次数就行了

DP出f[i]为i及其Parent祖先出现次数>=k有多少字符串(注意一个状态贡献的字符串为t[par].val-t[u].val),然后在跑一遍每个字符串得到答案就行了

然后就做完了。时间复杂度\(O(L^{1.5})\)

co int N=2e5;
string s[N];
int last=1,tot=1;
int ch[N][26],fa[N],len[N];
void extend(int c){
int p=last,cur=last=++tot;
len[cur]=len[p]+1;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=cur;
if(!p) fa[cur]=1;
else{
int q=ch[p][c];
if(len[q]==len[p]+1) fa[cur]=q;
else{
int clone=++tot;
memcpy(ch[clone],ch[q],sizeof ch[q]);
fa[clone]=fa[q],len[clone]=len[p]+1;
fa[cur]=fa[q]=clone;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=clone;
}
}
}
int vis[N],times[N],sum[N];
void dfs(int x){
if(x==1||vis[x]) return;
vis[x]=1;
dfs(fa[x]);
sum[x]+=sum[fa[x]];
}
int main(){
ios::sync_with_stdio(0);
int n,k;
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>s[i];
last=1;
for(int j=0;j<s[i].length();++j) extend(s[i][j]-'a');
}
// GetTimes
for(int i=1;i<=n;++i){
int now=1;
for(int j=0;j<s[i].length();++j){
now=ch[now][s[i][j]-'a'];
for(int t=now;t&&vis[t]!=i;t=fa[t]) vis[t]=i,++times[t];
}
}
for(int i=1;i<=tot;++i) sum[i]=(times[i]>=k)*(len[i]-len[fa[i]]);
memset(vis,0,sizeof vis);
for(int i=1;i<=tot;++i) dfs(i);
for(int i=1;i<=n;++i){
int ans=0,now=1;
for(int j=0;j<s[i].length();++j)
now=ch[now][s[i][j]-'a'],ans+=sum[now];
printf("%d ",ans);
}
return 0;
}

BZOJ3277 串 和 BZOJ3473 字符串的更多相关文章

  1. BZOJ3473&&BZOJ3277串

    BZOJ3473&&BZOJ3277串 题面 自己找去 HINT 对于所有串建立一个广义后缀自动机,对于每一个节点开一个set表示这个节点接受的子串在哪些串里出现过,然后在parent ...

  2. 16进制串与ASCII字符串相互转换

    提供两个函数,方便十六进制串与ASCII 字符串之间的相互转换,使用函数需要注意的是返回的串是在堆上通过 calloc 分配的,所以,记得使用完返回值释放该块,并且将指向该块的指针 =NULL .// ...

  3. bzoj3473: 字符串 && bzoj3277串

    3473: 字符串 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 121  Solved: 53[Submit][Status][Discuss] D ...

  4. bzoj3473字符串&bzoj3277串

    题意:给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串.注意本质相同的子串多次出现算多次,如1 1 aaa这组数据答案为6,贡献1WA.代码里有些部分是为了 ...

  5. BZOJ3277——串

    0.题意:给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). 1.分析:这个题我问了吴大爷做法 首先建立后缀自动机,然后利用离线搞出每一个 ...

  6. BZOJ3473: 字符串

    3473: 字符串 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 109  Solved: 47[Submit][Status] Descriptio ...

  7. BZOJ 3277: 串/ BZOJ 3473: 字符串 ( 后缀数组 + RMQ + 二分 )

    CF原题(http://codeforces.com/blog/entry/4849, 204E), CF的解法是O(Nlog^2N)的..记某个字符串以第i位开头的字符串对答案的贡献f(i), 那么 ...

  8. BZOJ3473: 字符串【后缀数组+思维】

    Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...

  9. bzoj 3277 串 && bzoj 3473 字符串 && bzoj 2780 [Spoj]8093 Sevenk Love Oimaster——广义后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3277 https://www.lydsy.com/JudgeOnline/problem.p ...

随机推荐

  1. elasticsearch 管理常用命令集合

    elasticsearch rest api遵循的格式为: curl -X<REST Verb> <Node>:<Port>/<Index>/<T ...

  2. 从一个案例窥探ORACLE的PASSWORD_VERSIONS

    1.环境说明 ORACLE 客户端版本 11.2.0.1 ORACLE 服务端版本 12.2.0.1 2.异常现象 客户端(下文也称为Cp)访问服务端(Sp),报了一个错误: Figure 1 以错误 ...

  3. 学习记录-java基础部分(一)

    学习记录-java基础部分(一) 参考:GitHub上的知名项目:javaGuide : https://github.com/Snailclimb/JavaGuide/blob/master/doc ...

  4. Influx Sql系列教程零:安装及influx-cli使用姿势介绍

    influxdb 时序数据库,因为实际业务中使用到了,然而并没有发现有特别好的文章,完整的介绍influx sql的使用姿势,因此记录下实际开发中学习的体会,主要参考来自于官方文档 Influx Qu ...

  5. LeetCode 235. 二叉搜索树的最近公共祖先 32

    235. 二叉搜索树的最近公共祖先 235. Lowest Common Ancestor of a Binary Search Tree 题目描述 给定一个二叉搜索树,找到该树中两个指定节点的最近公 ...

  6. Netty--索引

    Netty 入门示例 Netty原理架构解析 Netty 基本原理 Netty面试题 阿里的Netty知识点你又了解多少

  7. 《游戏引擎构架Game Engine Architecture》略读笔记

    <游戏引擎构架Game Engine Architecture>略读笔记 分析标题作者 分析目录 选取感兴趣的章节阅读 25分钟略读完章节 分析标题作者 此书是一本帮助人入行做游戏的书,也 ...

  8. Go 参数传递

    Go参数传递 在面试中,经常会被问起,这门语言的参数传递是值传递还是引用传递,当然,大部分情况下我们都会提前准备,有恃无恐,但还是希望能够精益求精嘛,所以针对Go语言来分析,Go传参是值传递还是引用传 ...

  9. ansible-playbook的简单传参方式

    基本语法:     ansible-playbook -v -i myhost  test.yml -e "name=xiaoming"    // -v  是看运行细节.要更细节 ...

  10. 苹果手机浏览器的$(document).on(“click”,function(){}) 绑定的事件点击无效

    需要给对应的元素加上 cursor: pointer  的css样式才可以生效点击事件: