2018.12.15 poj3415 Common Substrings(后缀自动机)
传送门
后缀自动机基础题。
给两个字符串,让你求长度不小于kkk的公共子串的数量。
这题可以用后缀自动机解决废话
考虑对其中一个字串建出后缀自动机,然后用另一个在上面跑,注意到如果一个状态有贡献的话,从它到根的状态都会有贡献,因此我们给每个节点打一个懒标记最后再统计一次答案即可。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ri register int
using namespace std;
const int N=2e5+5;
typedef long long ll;
int k,n;
char s[N];
inline int calc(char c){return c>='a'&&c<='z'?c-'a':c-'A'+26;}
struct SAM{
int tot,rt,last,len[N],link[N],son[N][60],siz[N],lz[N],cnt[N],rk[N];
inline void init(){
memset(len,0,sizeof(len)),memset(siz,0,sizeof(siz)),memset(rk,0,sizeof(rk)),memset(son,0,sizeof(son));
memset(link,0,sizeof(link)),memset(cnt,0,sizeof(cnt)),memset(lz,0,sizeof(lz)),tot=last=rt=1,len[0]=-1;
}
inline void expend(int x){
int p=last,np=++tot;
siz[last=np]=1,len[np]=len[p]+1;
while(p&&!son[p][x])son[p][x]=np,p=link[p];
if(!p){link[np]=rt;return;}
int q=son[p][x],nq;
if(len[q]==len[p]+1){link[np]=q;return;}
len[nq=++tot]=len[p]+1,memcpy(son[nq],son[q],sizeof(son[q])),link[nq]=link[q];
while(p&&son[p][x]==q)son[p][x]=nq,p=link[p];
link[q]=link[np]=nq;
}
inline void topsort(){
for(ri i=1;i<=tot;++i)++cnt[len[i]];
for(ri i=1;i<=last;++i)cnt[i]+=cnt[i-1];
for(ri i=1;i<=tot;++i)rk[cnt[len[i]]--]=i;
for(ri i=tot;i;--i)siz[link[rk[i]]]+=siz[rk[i]];
}
inline void query(){
topsort();
int p=1,nowlen=0;
ll ans=0;
for(ri i=1;i<=n;++i){
int x=calc(s[i]);
if(son[p][x])p=son[p][x],++nowlen;
else{
while(p&&!son[p][x])p=link[p];
if(!p)p=1,nowlen=0;
else nowlen=len[p]+1,p=son[p][x];
}
if(nowlen>=k){
ans+=(ll)(nowlen-max(k,len[link[p]]+1)+1)*siz[p];
if(len[link[p]]>=k)++lz[link[p]];
}
}
for(ri i=tot;i;--i){
p=rk[i];
ans+=(ll)lz[p]*siz[p]*(len[p]-max(k,len[link[p]]+1)+1);
if(len[link[p]]>=k)lz[link[p]]+=lz[p];
}
cout<<ans<<'\n';
}
}sam;
int main(){
while(scanf("%d",&k),k){
scanf("%s",s+1),n=strlen(s+1),sam.init();
for(ri i=1;i<=n;++i)sam.expend(calc(s[i]));
scanf("%s",s+1),n=strlen(s+1),sam.query();
}
return 0;
}
2018.12.15 poj3415 Common Substrings(后缀自动机)的更多相关文章
- 2018.12.15 hdu4641 K-string(后缀自动机)
传送门 后缀自动机基础题. 题意简述:支持动态在串尾插入字符,查询在串中出现超过kkk次的子串的个数. 动态修改samsamsam,每次增量构造好了之后在parentparentparent树上从新建 ...
- POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K ...
- POJ3415 Common Substrings(后缀数组 单调栈)
借用罗穗骞论文中的讲解: 计算A 的所有后缀和B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于k 的部分全部加起来.先将两个字符串连起来,中间用一个没有出现过的字符隔开.按height ...
- poj3415 Common Substrings (后缀数组+单调队列)
Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 9414 Accepted: 3123 Description A sub ...
- 2018.12.22 bzoj3277: 串(后缀自动机+启发式合并)
传送门 跟这道题是一模一样的. 于是本蒟蒻又写了一遍10min1A庆祝 代码: #include<bits/stdc++.h> #define ri register int using ...
- 2018.12.22 bzoj3473: 字符串(后缀自动机+启发式合并)
传送门 调代码调的我怀疑人生. 启发式合并用迭代写怎么都跑不过(雾 换成了dfsdfsdfs版本的终于过了233. 题意简述:求给出nnn个字串,对于每个给定的字串求出其有多少个字串在至少kkk个剩下 ...
- Tencent Cloud Developers Conference(2018.12.15)
时间:2018.12.15地点:北京朝阳悠唐皇冠假日酒店
- 2018.12.15 spoj Substrings(后缀自动机)
传送门 后缀自动机基础题. 求长度为iii的子串出现次数的最大值. 对原串建出samsamsam,然后用sizsizsiz更新每个maxlenmaxlenmaxlen的答案. 然后由于后缀链接将其转化 ...
- 2018.12.15 spoj Longest Common Substring II(后缀自动机)
传送门 后缀自动机基础题. 给出10个串求最长公共子串. 我们对其中一个建一个samsamsam,然后用剩下九个去更新范围即可. 代码: #include<bits/stdc++.h> # ...
随机推荐
- TOJ3097: 单词后缀 (字典树 or map瞎搞)
传送门 (<---可以点击的~) 时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte 描述 有些英语单词后缀都是一样的,现在我们需要从给定的一堆单词里 ...
- c#: UrlDecode()
1.源起: KV需要解析从插件传来的URL网址,因为其可能经过编码,所以需要解码. 初用System.Web.HttpUtility.UrlDecode()这个函数,但根据用户环境crash场景,发现 ...
- spring boot 2.0 与FASTDFS进行整合
只支持在spring-boot 2.0以及以上版本中使用 1.pom.xml 里引入FASTDFS的依赖,toobato与fastdfs作者一起,将fastdfs的功能进行了重构与简化 <!-- ...
- day 31 表单标签,CSS
一. HTML表单标签 HTML表单用于搜集不同类型的用户输入,然后把数据提交给服务器处理. 常用的表单标签: 标签 作用 form 所有表单标签的根标签 input 输入标签,包括单行输入框.密码框 ...
- day 30 HTML
HTML: 超文本标记语言(Hyper Text Markup Language) Html基本结构 <!DOCTYPE html> <html> <!-- 定义HTML ...
- 序列化_Transient
要实际的操作一下Serialize的代码Demo, 加深理解(某投行很喜欢问这个问题):transient关键字虽然目前还没有人面试过我,但是也是个考点
- JAVA虚拟机是?为什么称作是“平台无关的语言”?
Java虚拟机(Java Virtual Machine)简称JVM ,它是抽象化的计算机,有自己完善的硬体架构,如处理器.堆栈.寄存器等,还具有相应的指令系统.JVM屏蔽了与具体操作系统平台相关的信 ...
- Informatica_(4)工作流
三.workflow执行.监控 workflow是PowerCenter的执行单元: 一个workflow包括一个或者多个session(或task). 1.session session是mappi ...
- Oracle_PL/SQL(1) 匿名块
1. PL/SQL 简介PL/SQL是一种比较复杂的程序设计语言, 用于从各种环境中访问Oracle数据库.为什么使用PL/SQL?Orade是一种关系型数据库, 用来访问关系型数据库的语言是 “结构 ...
- Liunx 重定向,管道符(转)
原作网址:http://blog.csdn.net/qq_16811963/article/details/52997178 输出重定向 >代表以覆盖的方式将命令的正确输出输出到指定的文件或设备 ...