loj2064[HAOI2016]找相同字符
题意:给你两个字符串,问其中各取一个子串,有多少对相同?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]找相同字符的更多相关文章
- BZOJ 4566: [Haoi2016]找相同字符 [后缀自动机]
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 275 Solved: 155[Submit][Statu ...
- bzoj4566 / P3181 [HAOI2016]找相同字符
P3181 [HAOI2016]找相同字符 后缀自动机 (正解应是广义后缀自动机) 并不会广义后缀自动机. 然鹅可以用普通的后缀自动机. 我们先引入一个问题:算出从一个串内取任意两个不重合子串完全 ...
- 【BZOJ4566】[HAOI2016]找相同字符
[BZOJ4566][HAOI2016]找相同字符 题面 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 其中\(1\le ...
- [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1212 Solved: 694[Submit][Stat ...
- 【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈
[BZOJ4566][Haoi2016]找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同 ...
- bzoj 4566 [Haoi2016]找相同字符SA
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 128 Solved: 75[Submit][Status ...
- [Bzoj4566][Haoi2016]找相同字符(广义后缀自动机)
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 861 Solved: 495[Submit][Statu ...
- BZOJ_4566_[Haoi2016]找相同字符_后缀自动机
BZOJ_4566_[Haoi2016]找相同字符_后缀自动机 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有 ...
- [HAOI2016] 找相同字符 - 后缀数组,单调栈
[HAOI2016] 找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. \(n,m \l ...
随机推荐
- 表结构转excel
SELECTCOLUMN_NAME 列名,COLUMN_TYPE 数据类型,DATA_TYPE 字段类型,CHARACTER_MAXIMUM_LENGTH 长度,IS_NULLABLE 是否为空,CO ...
- java--split,index,StringTokenizer比较
import java.util.StringTokenizer; public class SplitDemo { //jdk8 public static void main(String[] a ...
- sqlserver数据导入问题:报错“对COM组件的调用返回了错误HRESULT E_FAIL”
SQL server 2008,导出了两个sql文件. 打开第一个文件,没有问题,建好相应的数据库,运行脚本,即可导入. 第二个文件却遇到问题,始终报错“对COM组件的调用返回了错误HRESULT E ...
- C/C++ C++ 11 std::bind()
{ #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA ...
- spring data jpa sql
CREATE TABLE cst_customer ( cust_id bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)', cust_name ...
- hdu 4826 Labyrinth(简单dp)
Description 度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格,且只能向上向下向 ...
- 洛谷P1122 最大子树和 (树状dp)
题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...
- 2019 牛客暑期多校 B generator 1 (矩阵快速幂+倍增)
题目:https://ac.nowcoder.com/acm/contest/885/B 题意:给你x0,x1,让你求出xn,递推式时xn=a*xn-1+b*xn-2 思路:这个n特别大,我自己没有摸 ...
- 为什么我markdown里的数学公式全崩了???
目录 try a try ac is ok Typecho博客 https://www.diyifanwen.com/fanwen/dangyuanxindetihui/2665516.htm htt ...
- jq动画效果慢慢滚动到固定位置
function contentTop(top){ $('body,html').animate({ scrollTop: top }, 500 ); } 获取元素top传入即可 contentTop ...