题意:给你两个字符串,问其中各取一个子串,有多少对相同?n<=20W。

标程:

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=;
ll ans;
int p,np,cnt,fa[N],son[N][],tt[N],sz1[N],sz2[N],l[N],sl,tl,Cnt[N];
char a[N],b[N];
void sam(int c)
{
p=np; np=++cnt;l[np]=l[p]+;
if (son[p][c]&&l[son[p][c]]==l[p]+) {cnt--,np=son[p][c];return;}
for (;p&&!son[p][c];p=fa[p]) son[p][c]=np;
if (!p) fa[np]=;
else {
int q=son[p][c];
if (l[q]==l[p]+) fa[np]=q;
else {
int nq=++cnt;l[nq]=l[p]+;
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for (;p&&son[p][c]==q;p=fa[p]) son[p][c]=nq;
}
}
}
int main()
{
scanf("%s%s",a+,b+);
sl=strlen(a+);tl=strlen(b+);
cnt=np=;
for (int i=;i<=sl;i++) sam(a[i]-'a'),sz1[np]++;
np=;
for (int i=;i<=tl;i++) sam(b[i]-'a'),sz2[np]++;
for (int i=;i<=cnt;i++) Cnt[l[i]]++;
for (int i=;i<=cnt;i++) Cnt[i]+=Cnt[i-];
for (int i=;i<=cnt;i++) tt[Cnt[l[i]]--]=i;
for (int i=cnt;i>=;i--)
{
int x=tt[i];
sz1[fa[x]]+=sz1[x];sz2[fa[x]]+=sz2[x];
}
for (int i=;i<=cnt;i++) ans+=(ll)sz1[i]*sz2[i]*(l[i]-l[fa[i]]);
printf("%lld\n",ans);
return ;
}

题解:后缀自动机

参考了mjy0724的做法,把两个串的后缀自动机建在一起,对于每一个节点分别统计在A/B串中的出现次数,统计sz1[i]*sz2[i]*(l[i]-l[fa[i]])。

也可以一个串建Sam,另一个串在Sam上匹配,每次统计以新加入字符为后缀的字符串的匹配情况。匹配到的Sam节点以上的节点都是该节点的后缀,都要统计,做个树上前缀和。注意一下该点内部的匹配,l=min(l,dep[p])+1。

也可以用后缀数组做,加一个分隔符,利用height数组从小到大加入。

loj2064[HAOI2016]找相同字符的更多相关文章

  1. BZOJ 4566: [Haoi2016]找相同字符 [后缀自动机]

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

  2. bzoj4566 / P3181 [HAOI2016]找相同字符

    P3181 [HAOI2016]找相同字符 后缀自动机 (正解应是广义后缀自动机) 并不会广义后缀自动机. 然鹅可以用普通的后缀自动机.   我们先引入一个问题:算出从一个串内取任意两个不重合子串完全 ...

  3. 【BZOJ4566】[HAOI2016]找相同字符

    [BZOJ4566][HAOI2016]找相同字符 题面 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 其中\(1\le ...

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

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

  5. 【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈

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

  6. bzoj 4566 [Haoi2016]找相同字符SA

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 128  Solved: 75[Submit][Status ...

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

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

  8. BZOJ_4566_[Haoi2016]找相同字符_后缀自动机

    BZOJ_4566_[Haoi2016]找相同字符_后缀自动机 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有 ...

  9. [HAOI2016] 找相同字符 - 后缀数组,单调栈

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

随机推荐

  1. vue-router中的router-link的active-class

    vue-router中的router-link的active-class   在vue-router中要使用选中样式的方法有两种: 1.直接在路由js文件中配置linkActiveClass 2.在r ...

  2. v-bind属性,v-model属性,:model属性

    一.v-bind 1.将按钮的title(key)绑定为data里指定的值 强调<input type="button" value="按钮" v-bin ...

  3. JavaSE---Annotation

    1.概述 1.1 JDK1.5开始,java提供了对Annotation的支持: 1.2 Annotation其实就是 代码中的特殊标记,这些标记 可以在编译.类加载.运行时被读取,并执行相应的处理: ...

  4. java基础学习笔记二(接口、super、this)

    一.super 和 this的用法 主要解释一下引用构造函数的用法 super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句) this(参数):调用本类中另一种形式的构造函数(应 ...

  5. Nacos 常见问题及解决方法

    Nacos 开源至今已有一年,在这一年里,得到了很多用户的支持和反馈.在与社区的交流中,我们发现有一些问题出现的频率比较高,为了能够让用户更快的解决问题,我们总结了这篇常见问题及解决方法,这篇文章后续 ...

  6. centos下安装java jdk1.8

    ---恢复内容开始--- mysql密码修改了,发现还没装jdk,那就一起记录下来吧.虽然网上好多,但自己想查更方便了. 查看有没有装jdk #java -version显示下面信息,不是oracle ...

  7. Oracle数据库中,sql中(+)(-)的含义

    SELECT *FROM TABLE1 A,TABLE2 B WHERE A.ID(+)=B.ID; 右连接=RIGHT JOIN SELECT *FROM TABLE1 A,TABLE2 B WHE ...

  8. 聊一聊 http2.0

    1. 我们认识http 协议,从最初的,客户端与服务器进行通讯,基于连接发生的请求与响应 在HTTP1.0时代,连接无法复用,每次下完单,都被强制登出/关机,下一次下单,就得重新登录. 为了解决htt ...

  9. 析构中delete this

    查看下面代码如何出错 #include <iostream> using namespace std; class A { public: A() { p = this; } ~A() { ...

  10. Java学习之抽象类

    抽象类特点: 1.抽象方法必须定义在抽象类中2.abstract关键字修饰:只能修饰类和方法3.抽象类不能实例化4.抽象类中的方法要被使用,必须由子类重写所有的抽象方法,实例化其子类 如果子类只重写部 ...