【BZOJ4566】找相同字符(后缀自动机)
【BZOJ4566】找相同字符(后缀自动机)
题面
题解
看到多串处理,\(SA\)就连起来
\(SAM???\)
单串建自动机
然后其他串匹配
对于一个串建完\(SAM\)后
另一个串在\(SAM\)上匹配
记录当前匹配的最大长度
匹配了当前位置的话,就能产生一定的贡献
但是很显然,沿着\(parent\)往上,所有点都能够产生贡献
所以匹配完再沿着\(parent\)做一遍类似\(dp\)的东西算贡献
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 220000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Node
{
int son[26];
int ff,len;
}t[MAX<<1];
int last=1,tot=1;
int size[MAX<<1];
long long ans;
int f[MAX<<1],g[MAX<<1],a[MAX<<1],c[MAX<<1];
char ch[MAX];
void extend(int c)
{
int p=last,np=++tot;last=np;
t[np].len=t[p].len+1;
while(p&&!t[p].son[c])t[p].son[c]=np,p=t[p].ff;
if(!p)t[np].ff=1;
else
{
int q=t[p].son[c];
if(t[q].len==t[p].len+1)t[np].ff=q;
else
{
int nq=++tot;
t[nq]=t[q];
t[nq].len=t[p].len+1;
t[q].ff=t[np].ff=nq;
while(p&&t[p].son[c]==q)t[p].son[c]=nq,p=t[p].ff;
}
}
size[np]=1;
}
int main()
{
scanf("%s",ch+1);
for(int i=1,l=strlen(ch+1);i<=l;++i)extend(ch[i]-97);
for(int i=1;i<=tot;++i)c[t[i].len]++;
for(int i=1;i<=tot;++i)c[i]+=c[i-1];
for(int i=1;i<=tot;++i)a[c[t[i].len]--]=i;
for(int i=tot;i;--i)size[t[a[i]].ff]+=size[a[i]];
scanf("%s",ch+1);
for(int i=1,l=strlen(ch+1),now=1,len=0;i<=l;++i)
{
int c=ch[i]-97;
if(t[now].son[c])++len,now=t[now].son[c];
else
{
while(now&&!t[now].son[c])now=t[now].ff;
if(!now)now=1,len=0;
else len=t[now].len+1,now=t[now].son[c];
}
ans+=1ll*size[now]*(len-t[t[now].ff].len);
g[now]++;
}
for(int i=tot;i;--i)f[t[a[i]].ff]+=f[a[i]]+g[a[i]];
for(int i=1;i<=tot;++i)ans+=1ll*size[i]*f[i]*(t[i].len-t[t[i].ff].len);
printf("%lld\n",ans);
return 0;
}
【BZOJ4566】找相同字符(后缀自动机)的更多相关文章
- [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1212 Solved: 694[Submit][Stat ...
- 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]找相同字符(后缀自动机)
题意 题目链接 Sol 直接在SAM上乱搞 枚举前缀,用SAM统计可以匹配的后缀,具体在匹配的时候维护和当前节点能匹配的最大值 然后再把parent树上的点的贡献也统计上,这部分可以爆跳parent树 ...
- 【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈
[BZOJ4566][Haoi2016]找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同 ...
- [HAOI2016] 找相同字符 - 后缀数组,单调栈
[HAOI2016] 找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. \(n,m \l ...
- bzoj4566 找相同字符
题意:给定两个字符串,从中各取一个子串使之相同,有多少种取法.允许本质相同. 解:建立广义后缀自动机,对于每个串,分别统计cnt,之后每个点的cnt乘起来.记得开long long #include ...
- BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)
题目链接 给定两个字符串,求它们有多少个相同子串.相同串的位置不同算多个. POJ3145简化版. 后缀自动机做法见这儿,又快又好写(一下就看出差距了..) //13712kb 4076ms #inc ...
- bzoj4566 / P3181 [HAOI2016]找相同字符
P3181 [HAOI2016]找相同字符 后缀自动机 (正解应是广义后缀自动机) 并不会广义后缀自动机. 然鹅可以用普通的后缀自动机. 我们先引入一个问题:算出从一个串内取任意两个不重合子串完全 ...
随机推荐
- [Python Study Notes]WdSaveFormat 枚举
WdSaveFormat 枚举 指定要在保存文档时使用的格式. 版本信息 已添加版本: 名称 值 说明 wdFormatDocument 0 Microsoft Word 格式. wdFormatDO ...
- [Uva10601]Cubes
[Uva10601]Cubes 标签: 置换 burnside引理 题意 给你12跟长度相同的小木棍,每个小木棍有一个颜色.统计他们能拼成多少种不同的立方体.旋转后相同的立方体认为是相同的. 题解 这 ...
- VUE学习笔记之vue cli 构建项目
一.环境搭建: 1.安装node.js 从node.js官网下载并安装node,安装过程很简单,一路"下一步"就可以了.安装完成之后,打开命令行工具(win+r,然后输入cmd), ...
- Java 求集合的所有子集
递归方法调用,求解集合的所有子集. package ch01; import java.util.HashSet; import java.util.Iterator; import java.uti ...
- RAC节点两边存储名字不一致导致的故障及相关延伸
起因:一个客户的实际故障,该故障非常典型,其他客户类似的环境也非常多,所以很值得梳理并记录下来. 环境:Oracle 11.2.0.4 RAC(2 nodes)+ RHEL 6.6 共享存储:EMC ...
- PHP函数register_shutdown_function的用法
register_shutdown_function这个函数是在PHP程序运行结束之前调用的,用这个函数可以做很多,比如调用运行发生致命错误中止的原因,或者调试程序的执行时间等. PHP终止的情况有哪 ...
- markdown学习经验
文章首发于我的github博客 前言 markdown是一种简洁有力的文本编辑语言.由于它十分好用,我将所有的博客都换成了markdown编辑器. 学习方法 工具为先,从工具中学习,熟能生巧. 工具选 ...
- 独立游戏大电影 原名(Indie.Game)
电影链接 独立游戏大电影 感觉很不错呢!!
- ACdream 1068
我没有用二分法,直接构造最小数,既然题目保证答案一定存在那么与上界无关. 如给定S=16,它能构成的最小数为79,尽量用9补位,最高位为S%9.如果构造的数大于下界A,那么直接输出,因为这是S能构成的 ...
- H3C交换机的端口隔离
H3C端口隔离 1.同一个VLAN下隔离物理端口 2.在隔离组中的端口不能相互访问 3.隔离组内的端口,可以与同一VLAN下的其他端口通信 配置: [H3C]port-isolate group 1 ...