Processing math: 0%

YZOJ P3939 [HAOI2016]找相同字符

YZOJ P3939 [HAOI2016]找相同字符

时间限制:1000MS      内存限制:262144K

难度:6.5

  • 题目描述

给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。

两个方案不同当且仅当这两个子串中有一个位置不同。

  • 输入格式

两行,两个字符串 s_1, s_21 \leq \left|s_1\right|, \left|s_2\right|\leq 200000,字符串中只有小写字母。

  • 输出格式

输出一个整数表示答案

  • 样例输入

  • 样例输出

 

 

 

Source: BZOJ 4566


 

 

 

广义SAM 或者 在SAM上跑匹配 都能做。

比如建立 广义SAM,处理出每个节点的 right_1, right_2 集合的大小,然后答案就是 \sum\limits_{x}{\left(max_x-min_x+1\right) \times \left|right_1\right| \times \left|right_2\right|}

跑匹配的话有点复杂。

首先对 s_1 建立SAM,s_2 放在上面跑匹配,失配了就通过 parent 跳回去。

注意到若匹配到这一节点时已经匹配的长度为 len ,那么长度 \leq len 的字符串(为当前字符串的后缀)也都已经被匹配,即这个节点沿着 parent 树向上的所有节点都被匹配了。

所以按照拓扑序预处理每个节点完全被匹配对答案的贡献 ans,即通过 parent 树关系向下贡献,有 ans_x=ans_{parent_x}+\left(max_x-min_x+1\right) \times \left|right\right|

匹配到节点 x ,已经匹配的长度为 len,那么其对答案的贡献为 ans_{parent_x}+\left(len-min_x+1\right) \times \left|right\right|

 

 

 

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注