【BZOJ4566】找相同字符(后缀数组)

题面

BZOJ

题解

后缀数组的做法,应该不是很难想

首先看到两个不同的串,当然是接在一起求\(SA,height\)

那么,考虑一下暴力

在两个串各枚举一个后缀,他们的\(lcp\)就是对答案产生的贡献

现在优化一下,按照\(SA\)的顺序枚举来处理\(lcp\)

利用一个单调栈维护一下,每次记录一下前面有多少个的贡献和当前答案一样就好啦

只是有点难写。。。

#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 440000
#define ll long long
int n,gr[MAX];
int SA[MAX],hg[MAX],rk[MAX];
int a[MAX],t[MAX],x[MAX],y[MAX];
bool cmp(int i,int j,int k){return y[i]==y[j]&&y[i+k]==y[j+k];}
void GetSA()
{
int m=50;
for(int i=1;i<=n;++i)t[x[i]=a[i]]++;
for(int i=1;i<=m;++i)t[i]+=t[i-1];
for(int i=n;i>=1;--i)SA[t[x[i]]--]=i;
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(int i=1;i<=n;++i)y[i]=0;
for(int i=n-k+1;i<=n;++i)y[++p]=i;
for(int i=1;i<=n;++i)if(SA[i]>k)y[++p]=SA[i]-k;
for(int i=0;i<=m;++i)t[i]=0;
for(int i=1;i<=n;++i)t[x[y[i]]]++;
for(int i=1;i<=m;++i)t[i]+=t[i-1];
for(int i=n;i>=1;--i)SA[t[x[y[i]]]--]=y[i];
swap(x,y);
x[SA[1]]=p=1;
for(int i=2;i<=n;++i)x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
if(p>=n)break;
m=p;
}
for(int i=1;i<=n;++i)rk[SA[i]]=i;
for(int i=1,j=0;i<=n;++i)
{
if(j)--j;
while(a[i+j]==a[SA[rk[i]-1]+j])++j;
hg[rk[i]]=j;
}
}
int Q1[MAX],top1,S1[MAX];
int Q2[MAX],top2,S2[MAX];
ll ans,sum1,sum2;
char ch[MAX];
int main()
{
scanf("%s",ch+1);
for(int i=1,l=strlen(ch+1);i<=l;++i)a[++n]=ch[i]-96,gr[n]=1;
a[++n]=27;
scanf("%s",ch+1);
for(int i=1,l=strlen(ch+1);i<=l;++i)a[++n]=ch[i]-96,gr[n]=2;
GetSA();
for(int i=1,tot=0;i<n;++i)
{
ans+=(gr[SA[i]]==1)?sum2:sum1;
ll tmp1=0;
while(top1&&Q1[top1]>=hg[i+1])
{
tmp1+=S1[top1];
sum1-=1ll*(Q1[top1]-hg[i+1])*S1[top1];
--top1;
}
++top1;S1[top1]=tmp1;Q1[top1]=hg[i+1];
ll tmp2=0;
while(top2&&Q2[top2]>=hg[i+1])
{
tmp2+=S2[top2];
sum2-=1ll*(Q2[top2]-hg[i+1])*S2[top2];
--top2;
}
++top2;S2[top2]=tmp2;Q2[top2]=hg[i+1];
if(gr[SA[i]]==1)++S1[top1],sum1+=hg[i+1];
else ++S2[top2],sum2+=hg[i+1];
}
printf("%lld\n",ans);
return 0;
}

【BZOJ4566】找相同字符(后缀数组)的更多相关文章

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

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

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

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

  3. BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)

    题目链接 给定两个字符串,求它们有多少个相同子串.相同串的位置不同算多个. POJ3145简化版. 后缀自动机做法见这儿,又快又好写(一下就看出差距了..) //13712kb 4076ms #inc ...

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

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

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

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

  6. BZOJ 4566 JZYZOJ 1547 [haoi2016T5]找相同子串 后缀数组 并查集

    http://172.20.6.3/Problem_Show.asp?id=1547 http://www.lydsy.com/JudgeOnline/problem.php?id=4566 单纯后缀 ...

  7. BZOJ4566: [Haoi2016]找相同字符(后缀自动机)

    题意 题目链接 Sol 直接在SAM上乱搞 枚举前缀,用SAM统计可以匹配的后缀,具体在匹配的时候维护和当前节点能匹配的最大值 然后再把parent树上的点的贡献也统计上,这部分可以爆跳parent树 ...

  8. bzoj4566 找相同字符

    题意:给定两个字符串,从中各取一个子串使之相同,有多少种取法.允许本质相同. 解:建立广义后缀自动机,对于每个串,分别统计cnt,之后每个点的cnt乘起来.记得开long long #include ...

  9. HAOI2016 找相同字符 后缀自动机

    两个串,考虑一建一跑.枚举模式串的位置\(i\),考虑每次统计以\(i\)结尾的所有符合要求的串.在后缀自动机上走时记录当前匹配长度\(curlen\),则当前节点的贡献是\((curlen-len[ ...

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

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

随机推荐

  1. memcached 与 redis 的区别和具体应用场景

    1. Memcached简介 Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric为首开发的高性能分布式内存缓存服务器.其本质上就是一个 ...

  2. TensorFlow实战之实现自编码器过程

    关于本文说明,已同步本人另外一个博客地址位于http://blog.csdn.net/qq_37608890,详见http://blog.csdn.net/qq_37608890/article/de ...

  3. ThinkPHP的使用

    在public目录下使用命令行执行:php -S localhost:8888 route.php 无需使用服务器就可启动

  4. Sublime 远程连接 Linux服务器

    Sublime是一款强大的编辑器,它的强大体现在它强大的插件. 要实现Sublime 远程连接 Linux服务器,需要使用插件SFTP. 一. 插件安装 用Package Control安装插件按下C ...

  5. Ubuntu Linux 与 Windows 7双系统安装教程(图文)

    前期准备: 1. 备份你的重要数据到其他设备上,以防不测2. 准备linux镜像.可以到ubuntu官网下载iso格式的文件.(注意:如果你是双显卡,不要随便下.amd的双显卡请选择含有"a ...

  6. oracle12c各个版本对其需要的依赖包及系统参数的修改

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 以下是我在oracle官网上对oracle12c 各个版本的依赖包需 ...

  7. 【JavaWeb】图书管理系统【总结】

    感想 该项目是目前为止,我写过代码量最多的项目了.....虽然清楚是没有含金量的[跟着视频来写的],但感觉自己也在进步中...... 写的过程中,出了不少的问题.....非常多的Servlet,JSP ...

  8. MIPS中有关于分支指令及跳转寻址

    分支指令 分支指令包含该指令,和两个操作数,以及跳转的分支地址,该地址是相对于下一条指令的相对地址 分支指令占6位   操作数1占5位     操作数2占5位     分支指令16位 例如 bne  ...

  9. css渲染(一) 字体和文本

    一.字体属性 1.默认字体系列 chrome/opera:"宋体" firefox:"微软雅黑" safari/IE:Times,"宋体" ...

  10. 1.9 list 列表

    列表是什么? list是Python中的基本数据结构之一,属于可变序列,所以前文中讲的可变序列的通用操作都适用于list. 这一节讲列表的特性吧. 特性一: 列表是包含任意对象的有序集合,同一个列表中 ...