后缀自动姬好,好写好调好ac

原题:

给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两
个子串中有一个位置不同。
1 <=n1, n2<= 20000
 
之前写了个后缀数组+并查集的,因为我只会后缀数组……
后看看dalao们纷纷使用后缀自动姬秒题,决定提高一下自己姿势水平,学一发后缀自动姬
然后根本无法理解啊quq,现在板子差不多理解了,但是自动姬上做DP的延伸还是不能理解quq
多做题应该就能理解了吧……
这题dp具体思路是啥我也没搞懂,直接上结论
每个点的贡献:|right(x)|*(max[x]-max[fa[x]])
具体贡献到答案上,就搞一个b在当前节点上匹配的公共长度l,然后对答案的贡献就是|right(x)|*(l-max[fa[x]])
代码:
 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define ll long long
int rd(){int z=,mk=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mk=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mk;
}
char a[],b[]; int n,m;
int nxt[][],fa[],mx[],sz[];
int lst=,tt=;
int cnt[],cntrk[];
ll f[];
void ist(int x){
int p=lst,np=lst=++tt;
mx[np]=mx[p]+; sz[np]=;
while(!nxt[p][x] && p) nxt[p][x]=np,p=fa[p];
if(!p) fa[np]=;
else{
int q=nxt[p][x];
if(mx[p]+==mx[q]) fa[np]=q;
else{
int nq=++tt; mx[nq]=mx[p]+;
memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
fa[nq]=fa[q],fa[q]=fa[np]=nq;
while(nxt[p][x]==q) nxt[p][x]=nq,p=fa[p];
}
}
}
void gtcntrk(){
for(int i=;i<=tt;++i) ++cnt[mx[i]];
for(int i=;i<=n;++i) cnt[i]+=cnt[i-];
for(int i=tt;i;--i) cntrk[cnt[mx[i]]--]=i;
}
void gtf(){
for(int i=tt;i;--i) sz[fa[cntrk[i]]]+=sz[cntrk[i]];
for(int i=;i<=tt;++i)
f[cntrk[i]]=f[fa[cntrk[i]]]+(ll)sz[cntrk[i]]*(mx[cntrk[i]]-mx[fa[cntrk[i]]]);
}
int main(){//freopen("ddd.in","r",stdin);
scanf("%s%s",a+,b+); n=strlen(a+),m=strlen(b+);
for(int i=;i<=n;++i) ist(a[i]-'a');
gtcntrk(),gtf();
ll bwl=; int l=,tmp=,x;
for(int i=;i<=m;++i){
x=b[i]-'a';
if(nxt[tmp][x]) tmp=nxt[tmp][x],++l;
else{
while(!nxt[tmp][x] && tmp) tmp=fa[tmp];
if(!tmp) tmp=,l=;
else l=mx[tmp]+,tmp=nxt[tmp][x];
}
if(tmp!=) bwl+=f[fa[tmp]]+(ll)sz[tmp]*(l-mx[fa[tmp]]);
}
cout<<bwl<<endl;
return ;
}

【BZOJ4566】【HAOI2016】找相同字符的更多相关文章

  1. BZOJ4566 [Haoi2016]找相同字符【SAM】

    BZOJ4566 [Haoi2016]找相同字符 给定两个字符串\(s和t\),要求找出两个字符串中所有可以相互匹配的子串对的数量 首先考虑可以怎么做,我们可以枚举\(t\)串的前缀\(t'\),然后 ...

  2. [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1212  Solved: 694[Submit][Stat ...

  3. [Bzoj4566][Haoi2016]找相同字符(广义后缀自动机)

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 861  Solved: 495[Submit][Statu ...

  4. BZOJ4566 [Haoi2016]找相同字符 字符串 SAM

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4566.html 题目传送门 - BZOJ4566 题意 给定两个字符串 $s1$ 和 $s2$ ,问有 ...

  5. BZOJ4566: [Haoi2016]找相同字符

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...

  6. BZOJ4566: [Haoi2016]找相同字符(后缀自动机)

    题意 题目链接 Sol 直接在SAM上乱搞 枚举前缀,用SAM统计可以匹配的后缀,具体在匹配的时候维护和当前节点能匹配的最大值 然后再把parent树上的点的贡献也统计上,这部分可以爆跳parent树 ...

  7. BZOJ4566 Haoi2016 找相同字符【广义后缀自动机】

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...

  8. BZOJ4566:[HAOI2016]找相同字符(SAM)

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...

  9. BZOJ4566 [Haoi2016]找相同字符 【后缀数组】

    题目 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. 输入格式 两行,两个字符串s1,s2,长度分别为n1,n2.1 & ...

  10. BZOJ4566 HAOI2016找相同字符(后缀自动机)

    对第一个串建SAM,第二个串在上面跑,记录当前前缀匹配的最长后缀长度l,每次考虑当前前缀的贡献,对于当前所在节点显然是|right|*(l-len[fa]),而对于其parent树上所有祖先的贡献显然 ...

随机推荐

  1. Could not load driverClass ${driverClassName} 的解决方案

          对项目进行ssm整合的过程中,发现报这个错误:Could not load driverClass ${driverClassName} 不明所以,在网上找了半天,各种答案都有,最后终于找 ...

  2. xml解析与生成的学习资料

    xml解析与生成的学习资料:http://blog.csdn.net/u012325167/article/category/6129813 ----------------------------- ...

  3. 初识数据库、初识MySQL

    一.为什么要用数据库 # 1.将文件和程序存在一台机器上是很不合理的. # 2.操作文件是一件很麻烦的事. 所以就出现了一个新的概念 —— 数据库 你可以理解为 数据库 是一个可以在一台机器上独立工作 ...

  4. linux文件查看

    查看目录 #查看文件 使用  ls  命令,加上参数 -l 表示查看详细信息,-a 表示查看包含隐藏文件在内的文件.也可使用通配符,*代表任意个字符,? 表示单个字符. $ ls ch*.doc #表 ...

  5. Linux3.10.0块IO子系统流程(1)-- 上层提交请求

    Linux通用块层提供给上层的接口函数是submit_bio.上层在构造好bio之后,调用submit_bio提交给通用块层处理.   submit_bio函数如下:   void submit_bi ...

  6. Cracking The Coding Interview 5.6

    //Write a program to swap odd and even bits in an integer with as few instructions as possible (e.g. ...

  7. C数据结构 : 线性表 与 链表

    一.线性表 一般表现为数组,使用一组地址连续的存储单元依次存储数据元素,如图: 它具有如下特点: 长度固定,必须在分配内存之前确定数组的长度. 存储空间连续,即允许元素的随机访问. 存储密度大,内存中 ...

  8. confirm消息对话框

    function rec(){ var mymessage= confirm("你是女孩?") ; if(mymessage==true) { document.write(&qu ...

  9. Java实验2

    1.给定一组字符,编程输出里面数值最大者. package experiment; import java.util.Arrays; public class ShenYue { public sta ...

  10. easyui datagrid 首次不加载做法

    我们一般遇到首次不执行查询,只有你点击查询按钮才查询的功能 我使用easyui的datagird做法是这样的: onBeforeLoad: function (param) { var firstLo ...