2018.07.17 HAOI2016 找相同字符(SAM)
传送门
就是给两个字符串,让你求公共字串的个数。
本来大佬们都是用的广义后缀自动机,但我感觉后缀自动机已经可以做这道题了。我们对其中一个字串建出后缀自动机,然后用另外一个后缀自动机在上面统计贡献即可。
代码如下:
#include<bits/stdc++.h>
#define N 400005
#define ll long long
using namespace std;
char s[N];
int ch[N][26],n,root=1,tot[N],a[N];
ll ans=0,len[N],dp[N],siz[N];
struct suf{
int cnt,last,fa[N];
inline void insert(int c){
int p=last,newp=++cnt;
last=newp,len[newp]=len[p]+1;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=newp;
if(!p)fa[newp]=root;
else{
int q=ch[p][c];
if(len[p]+1==len[q])fa[newp]=q;
else{
int newq=++cnt;
len[newq]=len[p]+1;
memcpy(ch[newq],ch[q],sizeof(ch[q]));
fa[newq]=fa[q],fa[q]=fa[newp]=newq;
for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=newq;
}
}
siz[newp]=1;
}
inline void build(){
scanf("%s",s+1),n=strlen(s+1),last=cnt=1;
for(int i=1;i<=n;++i)insert(s[i]-'a');
}
inline void topsort(){
for(int i=1;i<=cnt;++i)++tot[len[i]];
for(int i=1;i<=cnt;++i)tot[i]+=tot[i-1];
for(int i=1;i<=cnt;++i)a[tot[len[i]]--]=i;
for(int i=cnt;i;--i){int p=a[i];siz[fa[p]]+=siz[p];}
for(int i=2;i<=cnt;++i){
int p=a[i];
dp[p]=(len[p]-len[fa[p]])*siz[p]+dp[fa[p]];
}
}
inline void calc(){
int p=1;
ll stp=0;
for(int i=1;i<=n;++i){
int x=s[i]-'a';
for(;p&&!ch[p][x];p=fa[p]);
if(!p)stp=0,p=1;
else stp=min(stp,len[p])+1;
p=ch[p][x];
ans+=dp[fa[p]]+(stp-len[fa[p]])*siz[p];
}
}
inline void solve(){
topsort();
scanf("%s",s+1);
calc();
printf("%lld",ans);
}
}sam;
int main(){
sam.build();
sam.solve();
return 0;
}
2018.07.17 HAOI2016 找相同字符(SAM)的更多相关文章
- 2018.07.17 后缀自动机模板(SAM)
洛谷传送门 这是一道后缀自动机的模板题,这道题让我切身体会到了后缀自动机的方便与好写. 代码如下: #include<bits/stdc++.h> #define N 2000005 #d ...
- BZOJ4566:[HAOI2016]找相同字符(SAM)
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
- BZOJ4566 [Haoi2016]找相同字符【SAM】
BZOJ4566 [Haoi2016]找相同字符 给定两个字符串\(s和t\),要求找出两个字符串中所有可以相互匹配的子串对的数量 首先考虑可以怎么做,我们可以枚举\(t\)串的前缀\(t'\),然后 ...
- 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]找相同字符(广义后缀自动机)
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 861 Solved: 495[Submit][Statu ...
- 【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 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同 ...
随机推荐
- ADODB 调用存储过程
追加参数法调用存储过程 追加参数通过CreateParameter方法,用来指定属性创建新的Parameter对象.具体语法如下: Set parameter = command.CreatePara ...
- 使用 C++11 编写类似 QT 的信号槽——上篇
了解 QT 的应该知道,QT 有一个信号槽 Singla-Slot 这样的东西.信号槽是 QT 的核心机制,用来替代函数指针,将不相关的对象绑定在一起,实现对象间的通信. 考虑为 Simple2D 添 ...
- Jquery无缝轮播图的制作
轮播是html页面中比较常见的一种展现形式,也是基础,把轮播图做好,是排版中比较关键的 1.首先是轮播的html元素放置:做轮播之前,要有一个初步的认识 2.每个元素的位置怎样摆放,也是很关键的,这里 ...
- Haskell语言学习笔记(61)Distributive
Distributive class Functor g => Distributive g where distribute :: Functor f => f (g a) -> ...
- Haskell语言学习笔记(40)Arrow(1)
Arrow class Category a => Arrow a where arr :: (b -> c) -> a b c first :: a b c -> a (b, ...
- 【344】Jupyter relevant problems
参考:Jupyter Notebook Tutorial: The Definitive Guide 参考:ipython notebook 如何修改一开始打开的文件夹路径? Ref: Install ...
- 处理【由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面】
处理[由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面] 详细错误:HTTP 错误 404.2 - Not Found. 由于 Web 服务器上的“ISAPI 和 ...
- 条件语句;for循环 嵌套复习
//打印数字,0,1,8,10,12,每一个数单独占一行 //在全部数字打印完毕之后在打印数字的个数和所有数的和 int count = 0; int sum = 0; for (int i = 0; ...
- Structs配置文件 zg项目介绍
Structs配置文件 1.以系统代码为名称 例:
- bootstrap下拉框的例子,提示Error: Bootstrap's JavaScript requires jQuery
bootstrap很多js依赖jquery,所以需要引入jquery 遇到的问题: 页面访问提示:Error: Bootstrap's JavaScript requires jQuery 解 ...