BZOJ3473 字符串 广义后缀自动机
今天主攻了下SAM 好多东西以前都没理解到
对于这道题 我们建一个自动机存所有串 每个穿last从1开始
对于自动机上每个点额外记一个cnt 表示能匹配到这个点的不同串个数
建完对每个串在自动机上匹配 把到的每个点$x$和$par[x],par[par[x]]…$的$cnt++$
然后就从父亲往儿子传递一下 这样每个点i就存了所有≤≤len[i]的数量 这里我用的拓扑序转移
最后再对每个串在自动机上跑一遍 统计答案就好啦~
#include<bits/stdc++.h>
#define bug(x) cout<<(#x)<<" "<<(x)<<endl
#define ll long long
/*
char *TT,*mo,but[(1<<15)+2];
#define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
using namespace std;
const int N=2e5+5;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll ans[N];
int n,k,amaz,tot,rt,last,cnt[N],ch[N][27],len[N],par[N],l[N],tmp[N],sum[N],dig[N],vis[N];
string a[N];
void extend(int x){
int p=last,np=++tot;
last=np,len[np]=len[p]+1;
for(;p&&!ch[p][x];p=par[p]) ch[p][x]=np;
if(!p) par[np]=rt;
else{
int q=ch[p][x];
if(len[q]==len[p]+1) par[np]=q;
else{
int nq=++tot;
memcpy(ch[nq],ch[q],sizeof ch[q]);
len[nq]=len[p]+1;
par[nq]=par[q];par[q]=par[np]=nq;
for(;p&&ch[p][x]==q;p=par[p]) ch[p][x]=nq;
}
}
}
void top(){
queue<int>q;
for(int i=1;i<=tot;i++) if(!dig[i]) q.push(i),tmp[++amaz]=i;
while(!q.empty()){
int x=q.front();q.pop();
if(!--dig[par[x]]) {
q.push(par[x]),tmp[++amaz]=par[x];
}
}
for(int i=amaz;i;i--) sum[tmp[i]]+=sum[par[tmp[i]]];
}
int main(){
#ifdef Devil_Gary
freopen("in.txt","r",stdin);
#endif
n=read(),k=read();
rt=tot=last=1;
for(int i=1;i<=n;i++){
cin>>a[i];
l[i]=a[i].length();
last=1;
for(int j=0;j<l[i];j++) extend(a[i][j]-'a');
}
for(int j=1;j<=n;j++){
int p=1;
for(int i=0;i<l[j];i++){
p=ch[p][a[j][i]-'a'];
int x=p;
while(x&&vis[x]!=j) {
cnt[x]++,vis[x]=j,x=par[x];
}
}
}
for(int i=1;i<=tot;i++) dig[par[i]]++,sum[i]=(cnt[i]>=k)?(len[i]-len[par[i]]):0;
top();
for(int j=1;j<=n;j++){
int p=1;
for(int i=0;i<l[j];i++){
p=ch[p][a[j][i]-'a'];
ans[j]+=sum[p];
}
printf("%lld ",ans[j]);
}
return 0;
}
BZOJ3473 字符串 广义后缀自动机的更多相关文章
- 【bzoj3277/bzoj3473】串/字符串 广义后缀自动机
题目描述 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). 输入 第一行两个整数n,k.接下来n行每行一个 ...
- BZOJ 3473: 字符串 [广义后缀自动机]
3473: 字符串 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 354 Solved: 160[Submit][Status][Discuss] ...
- BZOJ 3277 串 & BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析、启发式合并、线段树合并、主席树)
标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) ...
- 2018.12.22 bzoj3473: 字符串(后缀自动机+启发式合并)
传送门 调代码调的我怀疑人生. 启发式合并用迭代写怎么都跑不过(雾 换成了dfsdfsdfs版本的终于过了233. 题意简述:求给出nnn个字串,对于每个给定的字串求出其有多少个字串在至少kkk个剩下 ...
- BZOJ 3473 字符串 ——广义后缀自动机
这题就比较有趣了. 首先匹配一遍,然后统计子树叶子节点中包含大于等于k的节点个数(HH的项链) 然后就可以搞了. 关于合法的情况数,显然是l[i]-l[fa[i]],然后向下下传即可(YY一下). # ...
- BZOJ3473 字符串 【广义后缀自动机】
题目 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? 输入格式 第一行两个整数n,k. 接下来n行每行一个字符串. 输出格式 一行n个整数,第i个整数表 ...
- 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 ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串
https://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比 ...
- [bzoj3277==bzoj3473]出现k次子串计数——广义后缀自动机+STL
Brief Description 给定n个字符串,对于每个字符串,您需要求出在所有字符串中出现次数大于等于k次的子串个数. Algorithm Design 先建立一个广义后缀自动机,什么是广义后缀 ...
随机推荐
- 安装Visual Studio Scrum 1.0过程模板
近几年里,Scrum变成了相当流行的软件开发方法学.因为它轻量.可迭代且快速等优点,以致于在敏捷开发中极受欢迎.微软甚至将TFS2010自带的MSF Agile5.0过程模板做得像Scrum,开发者们 ...
- go语言 documentation
Documentation文档 The Go programming language is an open source project to make programmers more pro ...
- java基础24 线程、多线程及线程的生命周期(Thread)
1.1.进程 正在执行的程序称作为一个进程.进程负责了内存空间的划分 疑问1:windows电脑称之为多任务的操作系统,那么Windows是同时运行多个应用程序呢? 从宏观的角度:windows确实在 ...
- Github中展示demo
原文链接http://www.jianshu.com/p/75e30889e70a 第一步:找到Settings,点击 第二步:找到githubPages点击none,切换到master branch ...
- 修饰符(动态String数组篇)--- 常用 解除疑问。
1.无修饰符----是直接传基本类型的地址过来,并没有把基本类型的指针复制一份入栈,所以一旦修改就是修改原来的值. 2.const 修饰符 与 无修饰符一致. 3.var修饰符 与 上一致. 4.ou ...
- Linux下./configure && make && make install 编译安装和卸载
正常的编译安装/卸载: 源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install). configure文件是一个可执行的脚本文件,它有很多选项, ...
- SQL语句添加删除修改字段
用SQL语句添加删除修改字段1.增加字段 alter table docdsp add dspcodechar(200)2.删除字段 ALTER TABLE table_NAME ...
- SSIS 学习之旅 FTP文件传输-脚本任务
这一章主要讲解一下用脚本怎么把CSV文件抛送到FTP服务器上 设计: 通过Demon库的Users表数据生成CSV文件. 生成后的CSV文件抛送到FTP指定目录下. 控件的使用这里就不做详细讲 ...
- hdu 2069 1 5 10 25 50 这几种硬币 一共100个(母函数)
题意: 有50 25 10 5 1 的硬币 一共最多有100枚 输入n输出有多少种表示方法 Sample Input1126 Sample Output413 # include <iostre ...
- day5模块学习--XML模块
XML文件处理 XML文件处理,有好几种方式,这里介绍一下xml.etree.ElementTree as ET. 注意:xml.etree.ElementTree模块在应对恶意结构数据时显得并不安全 ...