Description

给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两
个子串中有一个位置不同。

Input

两行,两个字符串s1,s2,长度分别为n1,n2。1 <=n1, n2<= 200000,字符串中只有小写字母

Output

输出一个整数表示答案

Sample Input

aabb
bbaa

Sample Output

10

Solution

很容易可以想到,我们要对字符串$A$建立$SAM$,然后用$B$串在$A$上跑
只要能匹配到这个节点,那么它顺着$fa$指针向上的那一串节点都可以产生贡献。
每个节点的贡献是$|R(s)|*max((min(Max,temp)-Min+1),0)$,$temp$为当前匹配长度
实际上当匹配到某个节点$s$的时候,$now$一定大于等于$fa(s)$
所以上面的节点直接用$Max$更新就可以。需要特判的只是当前的节点

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#define N (400000+1000)
using namespace std; char s[N],t[N];
long long Ans; struct SAM
{
int son[N][],fa[N],step[N],right[N],wt[N],od[N];
int p,q,np,nq,last,cnt;
SAM(){last=++cnt;} void Insert(int x)
{
p=last; np=last=++cnt; step[np]=step[p]+; right[np]=;
while (!son[p][x] && p) son[p][x]=np,p=fa[p];
if (!p) fa[np]=;
else
{
q=son[p][x];
if (step[p]+==step[q]) fa[np]=q;
else
{
nq=++cnt; step[nq]=step[p]+;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
while (son[p][x]==q) son[p][x]=nq,p=fa[p];
}
}
}
void Init()
{
int len=strlen(s);
for (int i=; i<=cnt; ++i) wt[step[i]]++;
for (int i=; i<=len; ++i) wt[i]+=wt[i-];
for (int i=cnt; i>=; --i) od[wt[step[i]]--]=i;
for (int i=cnt; i>=; --i) right[fa[od[i]]]+=right[od[i]];
}
void Solve(char s[])
{
int now=,len=strlen(s),temp=;
for (int i=; i<len; ++i)
{
while (now && !son[now][s[i]-'a'])
now=fa[now],temp=step[now];
if (now==){now=; continue;}
now=son[now][s[i]-'a'],temp++;
Ans+=1ll*right[now]*(temp-step[fa[now]]);
int t=now;
while (fa[t]) t=fa[t],Ans+=1ll*right[t]*(step[t]-step[fa[t]]);
}
}
}SAM; int main()
{
scanf("%s%s",s,t);
int len=strlen(s);
for (int i=; i<len; ++i)
SAM.Insert(s[i]-'a');
SAM.Init();
SAM.Solve(t);
printf("%lld",Ans);
}

BZOJ4566:[HAOI2016]找相同字符(SAM)的更多相关文章

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

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

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

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

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

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

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

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

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

随机推荐

  1. 里氏替换原则(Liskov Substitution Principle) LSP

    using System; using System.Collections.Generic; using System.Text; namespace LiskovSubstitutionPrinc ...

  2. tgz 文件解压

    使用命令:tar zxvf ×××.tgz 即可进行解压 留作备忘

  3. (转)linux sed命令就是这么简单

    sed替换命令 原文:https://www.cnblogs.com/zd520pyx1314/p/6061337.html http://www.cnblogs.com/wangqiguo/p/67 ...

  4. 【ORACLE】sqlplus使用记录

    1.设置输出长度 SEGMENT_NAME--------------------------- BYTES----------TZ01_LOGIN_DATA 20971520 TZ02_EP_GAT ...

  5. 请以excel管理你的接口测试用例

    闲话休扯,上需求:自动读取.执行excel里面的接口测试用例,测试完成后,返回错误结果并发送邮件通知. 分析: 1.设计excel表格2.读取excel表格3.拼接url,发送请求4.汇总错误结果.发 ...

  6. 《腾讯游戏人生》微信小程序开发总结

    为打通游戏人生擂台赛与线下商家的O2O衔接,同时响应时下日臻火热的微信小程序,项目团队决定也开发一款针对性的微信小程序,以此方便商家在我们平台入驻并进行擂台赛事的创建和奖励的核销,进一步推广擂台赛的玩 ...

  7. 检测SQL Server表占用空间大小SQL

    检测SQL Server表占用空间大小SQL,要先选择需要查询的数据库,然后点击执行下面脚本. ),ROWS ),reserved ) ,Data ) ,index_size ) ,Unused ) ...

  8. js 匹配中文字符串(也包含日文和韩文)

    <script> var str="payTypeNam门诊账户\n\t"; document.write(str.match(/[\u4E00-\u9FA5\uF90 ...

  9. C#利用事件与委托进行窗体间传值简单小例子

    本篇博客是利用C#委托与事件进行窗体间传值的简单小例子 委托与事件的详细解释大家可以参照张子阳的博客: http://www.tracefact.net/CSharp-Programming/Dele ...

  10. OLEDB存取BLOB型数据

    现代数据库系统除了支持一些标准的通用数据类型以外,大多数还支持一种称之为BLOB型的数据. BLOB全称为big large object bytes, 大二进制对象类型,这种类型的数据通常用于存储文 ...