BZOJ4566 HAOI2016找相同字符(后缀自动机)
对第一个串建SAM,第二个串在上面跑,记录当前前缀匹配的最长后缀长度l,每次考虑当前前缀的贡献,对于当前所在节点显然是|right|*(l-len[fa]),而对于其parent树上所有祖先的贡献显然是|right|*(len-len[fa])。预处理一下就好了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 400010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,cnt=1,last=1,son[N][26],fail[N],len[N],id[N],size[N],tot[N];
ll ans,f[N],val[N];
char a[N],b[N];
void ins(int c)
{
int x=++cnt,p=last;last=x;len[x]=len[p]+1;size[x]=1;
while (!son[p][c]) son[p][c]=x,p=fail[p];
if (!p) fail[x]=1;
else
{
int q=son[p][c];
if (len[p]+1==len[q]) fail[x]=q;
else
{
int y=++cnt;
len[y]=len[p]+1;
memcpy(son[y],son[q],sizeof(son[q]));
fail[y]=fail[q],fail[q]=fail[x]=y;
while (son[p][c]==q) son[p][c]=y,p=fail[p];
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
scanf("%s",a+1);n=strlen(a+1);
scanf("%s",b+1);m=strlen(b+1);
for (int i=1;i<=n;i++) ins(a[i]-'a');
for (int i=1;i<=cnt;i++) tot[len[i]]++;
for (int i=1;i<=n;i++) tot[i]+=tot[i-1];
for (int i=1;i<=cnt;i++) id[tot[len[i]]--]=i;
for (int i=cnt;i>=1;i--) size[fail[id[i]]]+=size[id[i]];
for (int i=1;i<=cnt;i++) val[id[i]]=val[fail[id[i]]]+1ll*size[id[i]]*(len[id[i]]-len[fail[id[i]]]);
int k=1,l=0;
for (int i=1;i<=m;i++)
{
while (!son[k][b[i]-'a']&&k) k=fail[k],l=len[k];
if (!k) k=1,l=0;
else l++,k=son[k][b[i]-'a'];
ans+=val[fail[k]]+1ll*size[k]*(l-len[fail[k]]);
}
cout<<ans;
return 0;
}
BZOJ4566 HAOI2016找相同字符(后缀自动机)的更多相关文章
- [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1212 Solved: 694[Submit][Stat ...
- BZOJ4566: [Haoi2016]找相同字符(后缀自动机)
题意 题目链接 Sol 直接在SAM上乱搞 枚举前缀,用SAM统计可以匹配的后缀,具体在匹配的时候维护和当前节点能匹配的最大值 然后再把parent树上的点的贡献也统计上,这部分可以爆跳parent树 ...
- BZOJ 4566: [Haoi2016]找相同字符 [后缀自动机]
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 275 Solved: 155[Submit][Statu ...
- HAOI2016 找相同字符 后缀自动机
两个串,考虑一建一跑.枚举模式串的位置\(i\),考虑每次统计以\(i\)结尾的所有符合要求的串.在后缀自动机上走时记录当前匹配长度\(curlen\),则当前节点的贡献是\((curlen-len[ ...
- BZOJ4566 [Haoi2016]找相同字符【SAM】
BZOJ4566 [Haoi2016]找相同字符 给定两个字符串\(s和t\),要求找出两个字符串中所有可以相互匹配的子串对的数量 首先考虑可以怎么做,我们可以枚举\(t\)串的前缀\(t'\),然后 ...
- [Bzoj4566][Haoi2016]找相同字符(广义后缀自动机)
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 861 Solved: 495[Submit][Statu ...
- 【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈
[BZOJ4566][Haoi2016]找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同 ...
- [HAOI2016] 找相同字符 - 后缀数组,单调栈
[HAOI2016] 找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. \(n,m \l ...
- BZOJ4566 Haoi2016 找相同字符【广义后缀自动机】
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
- BZOJ4566: [Haoi2016]找相同字符
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
随机推荐
- 7.linux磁盘管理 分区 建立文件系统 挂载使用
一.磁盘管理 分区 建立文件系统 挂载使用 逻辑卷建立 磁盘阵列的建立 磁盘配额设定 fdisk -l 查看磁盘信息 df -Th 查看硬盘对应的 ...
- Vue源码分析(二) : Vue实例挂载
Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...
- 转: mysql的取整函数
一.ROUND()函数用法 ROUND(X) -- 表示将值 X 四舍五入为整数,无小数位 ROUND(X,D) -- 表示将值 X 四舍五入为小数点后 D 位的数值,D为小数点后小数位数.若要 ...
- 【译】Solr in Action 第二章
2.1 2.2 2.3 基本废话 2.4 基本废话
- 原创 linux 爬虫拨号服务器完整设置
[root@cloud ~]# cat /home/bh.sh #!/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin:/sbin/ifconfig /usr/s ...
- main方法的详解
格式 * public static void main(String[] args) {} 针对格式的解释 public 被jvm调用,访问权限足够大. static 被jvm调用,不用创建对象,直 ...
- VL10B 采购订单转DN
传入采购订单项目建交货单 FUNCTION zmmfmXXXX. *"------------------------------------------------------------ ...
- (十六)集合框架(Collection和Map)和比较器(Comparable和comparator)
一.集合框架 1.1 为什么要使用集合框架? 当我们需要保持一组一样(类型相同)的元素的时候,我们应该使用一个容器来保存,数组就是这样一个容器. 那么,数组的缺点是什么呢? 数组一旦定义,长度将不能再 ...
- 使用redis做为MySQL的缓存-C语言编写UDF
介绍 在实际项目中,MySQL数据库服务器有时会位于另外一台主机,需要通过网络来访问数据库:即使应用程序与MySQL数据库在同一个主机中,访问MySQL也涉及到磁盘IO操作(MySQL也有一些数据预读 ...
- rabbitMQ tipic 模式
RabbitMQ消息队列(八)-通过Topic主题模式分发消息(.Net Core版) 前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对di ...