题目要求的就是B的每个字串在A中的出现次数之和。
我们考虑先建出A串的SAM,每个点所代表的串的个数就是 |Righti|∗(Maxi−Maxfai) |Right_i|*(Max_i-Max_{fa_i})。我们可以发现经过一个点的时候,它在parent树上所有祖先代表的串出现次数也都加一,所以我们设 Sumi Sum_i为它和它祖先所代表串个数之和。
那么把B放在SAM上面跑,每经过一个点 x x,对答案的贡献为Sumfax+|Rightx|∗(dis−Maxfax)Sum_{fa_x}+|Right_x|*(dis-Max_{fa_x}), dis dis是B串走到当前节点可拓展的最长长度。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=400010;
char s[maxn];
struct sam
{int cnt,last,a[maxn][26],mx[maxn],fa[maxn],buc[maxn],ord[maxn];ll ri[maxn],sum[maxn];sam(){last=cnt=1;for(int i=0;i<=25;i++)a[0][i]=1;mx[0]=-1;}void extend(int c){int p=last,np=last=++cnt;mx[np]=mx[p]+1;ri[np]=1;for(;p&&!a[p][c];p=fa[p]) a[p][c]=np;int q=a[p][c];if(mx[q]==mx[p]+1) {fa[np]=q;return;}int nq=++cnt;mx[nq]=mx[p]+1;for(int ic=0;ic<26;ic++)a[nq][ic]=a[q][ic];fa[nq]=fa[q];fa[q]=fa[np]=nq;for(;p&&a[p][c]==q;p=fa[p]) a[p][c]=nq; }void pre(){for(int i=1;i<=cnt;i++) buc[mx[i]]++;for(int i=1;i<=cnt;i++) buc[i]+=buc[i-1];for(int i=cnt;i;i--) ord[buc[mx[i]]--]=i;for(int i=cnt;i;i--) ri[fa[ord[i]]]+=ri[ord[i]];for(int i=2;i<=cnt;i++) sum[ord[i]]=sum[fa[ord[i]]]+ri[ord[i]]*(mx[ord[i]]-mx[fa[ord[i]]]);}ll run(int l){ll re=0;for(int i=1,p=1,dis=0;i<=l;i++){int c=s[i]-'a';if(a[p][c]) dis++;else{   while(p&&!a[p][c]) p=fa[p];dis=mx[p]+1;}p=a[p][c];re+=sum[fa[p]]+ri[p]*(dis-mx[fa[p]]);}return re;}
}Tsam;
int main()
{scanf("%s",s+1);int len=strlen(s+1);for(int i=1;i<=len;i++)Tsam.extend(s[i]-'a');Tsam.pre();scanf("%s",s+1);printf("%lld",Tsam.run(strlen(s+1)));return 0;
}

[BZOJ4566][HAOI2016]找相同字符 后缀自动机相关推荐

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

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

  2. [bzoj4566][HAOI2016]找相同字符(后缀数组)

    题目 传送门 题解 这里:把两个串用一个很大的字符连接起来,求一个后缀数组. 考虑怎样暴力的算答案. 在 rank  r a n k rank数组中从前往后枚举起点,对于每个枚举的起点,都暴力的往后扫 ...

  3. 【bzoj4566】找相同字符 后缀自动机

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=4566 [题解] 我们还是先把A串建成SAM,然后让B串在SAM上跑 因为相同子串数=不同长 ...

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

    BZOJ4566: [Haoi2016]找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数. 两个方案不同当且仅当这两个子串中有一个位置不同 ...

  5. [bzoj4566][HAOI2016]找相同字符

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MB Submit: 113 Solved: 64 [Submit][Status ...

  6. 【HAOI2016/BZOJ4566】找相同字符 后缀数组+单调栈

    原题走这里 鉴于我实在不是很懂单调栈和单调队列这一系列东西,所以我决定稍微具体讲一下单调栈. 恩,本题实质上就是求两个字符串的公共子串数,其中只要出现位置不同,就算是不同的子串. 处理多个字符串的经典 ...

  7. [洛谷P3181] [HAOI2016]找相同字符

    洛谷题目链接:[HAOI2016]找相同字符 题目描述 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 输入输出格式 输入 ...

  8. 【bzoj4566】[Haoi2016]找相同字符【后缀自动机】

    题目传送门 题解:在文本串上建后缀自动机,用模式串在后缀自动机上跑.扫一遍模式串,在后缀自动机上走,走不了就跳fail再走. 走的过程中,维护模式串与文本串匹配的最大长度,并且统计答案. 怎么统计答案 ...

  9. 4566: [Haoi2016]找相同字符 SAM

    折腾了好久.不过收获还是很多的.第一次自己去画SAM所建出来fail树.深入体会了这棵树的神奇性质. 当然,我最终靠着自己A掉了.(这是我第一次推SAM的性质(以前都是抄别人的,感觉自己好可耻),不过 ...

最新文章

  1. PyTorch 1.9发布,支持新API,可在边缘设备中执行
  2. 语音合成的语音相位图
  3. OPPO智能眼镜发布,撕掉手机标签,CEO陈明永罕见亮相砸500亿投研发
  4. python可以干嘛知乎-一行Python代码能做什么?
  5. WinForm 里面ListBox的问题
  6. LUA表 pairs, ipairs输出顺序问题
  7. SharePoint 2013 术语和术语集介绍
  8. JQuery中的一些重要方法
  9. 新乡学院2019计算机报名,新乡学院2019年招生章程
  10. pyspark 条件_删除pyspark中特定条件下的特定行
  11. 我的Delphi开发经验谈
  12. SpringBoot RabbitMQ 异步激活_注册邮箱
  13. 计算机配置作业2000,求一组近期装计算机配置清单 价格清楚
  14. 股市中的马太效应带给我们什么股票道理?
  15. dismiss和remove_eliminate, remove, dismiss的区别:新东方考研英语词汇辨析
  16. 对接快递100快递管家API之如何实现自动打单
  17. 报错解决——Failed to load resource: the server responded with a status of 404 (Not Found)
  18. 视频教程-微信公众平台深度开发v2.0第3季——二维码、模板消息-微信开发
  19. excel怎么拆分表格
  20. MPLS virtual private network PE-CE之间的路由协议(OSPF)

热门文章

  1. 利用 exploit-db 交叉编译 shellcode
  2. 3D打印机耗材ABS和PLA的区别
  3. 江西科技学院计算机二级考试,2014年上半年江西科技学院全国计算机二级考试报名通知...
  4. Array 数组的常用方法(含es6)
  5. js 数组内删除某个对象(或确定该对象索引值)
  6. 2.6.1 ADSL技术
  7. KS-检验(Kolmogorov-Smirnov test) -- 检验数据是否符合某种分布
  8. 《南京印象》之一《秦淮断章》
  9. php 分布存储,分布式存储原理是什么?
  10. Maven---本地仓库访问私服配置