BZOJ 4566 [Haoi2016]找相同字符 ——广义后缀自动机
建立广义后缀自动机。
然后统计子树中的siz,需要分开统计
然后对(l[i]-l[fa[i]])*siz[i][0]*siz[i][1]求和即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define maxn 800005 struct Suffix_Auto{
int go[maxn][26],l[maxn],siz[maxn],fa[maxn];
int last,cnt,v[maxn],q[maxn],rit[maxn][2];
char s[maxn];
void init()
{
last=cnt=1;
memset(go,0,sizeof go);
}
void add(int x,int id)
{
int p=last,q;
if (q=go[p][x])
{
if (l[q]==l[p]+1) last=q;
else
{
int nq=++cnt;
l[nq]=l[p]+1;
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q];
fa[q]=nq;
for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq;
last=nq;
}
}
else
{
int np=++cnt; l[np]=l[p]+1;
for (;p&&!go[p][x];p=fa[p]) go[p][x]=np;
if (!p) fa[np]=1;
else
{
q=go[p][x];
if (l[q]==l[p]+1) fa[np]=q;
else
{
int nq=++cnt;
l[nq]=l[p]+1;
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq;
}
}
last=np;
}
rit[last][id]++;
}
void build()
{
int n1;
init();
scanf("%s",s+1);
n1=strlen(s+1);
F(i,1,n1) add(s[i]-'a',0);
last=1;
scanf("%s",s+1);
n1=strlen(s+1);
F(i,1,n1) add(s[i]-'a',1);
}
void radix()
{
F(i,1,cnt) v[l[i]]++;
F(i,1,cnt) v[i]+=v[i-1];
D(i,cnt,1) q[v[l[i]]--]=i;
D(i,cnt,1)
{
rit[fa[q[i]]][0]+=rit[q[i]][0];
rit[fa[q[i]]][1]+=rit[q[i]][1];
}
ll ans=0;
F(i,1,cnt)
ans+=(ll)rit[i][0]*rit[i][1]*(l[i]-l[fa[i]]);
printf("%lld\n",ans);
}
void solve()
{
build();
radix();
}
}sam; int main(){sam.solve();}
BZOJ 4566 [Haoi2016]找相同字符 ——广义后缀自动机的更多相关文章
- bzoj 4566 [Haoi2016]找相同字符——广义后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4566 每个后缀结尾处 ct[ ] = 1 ,按拓扑序 dp 一下就能求出 right 集合的 ...
- [HAOI2016]找相同字符 广义后缀自动机_统计出现次数
题目描述:给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 输入输出格式输入格式:两行,两个字符串 s1,s2,长度分别为n ...
- BZOJ_4566_[Haoi2016]找相同字符_后缀自动机
BZOJ_4566_[Haoi2016]找相同字符_后缀自动机 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有 ...
- BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机)
BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机) 题面 自己找去 HINT 给定两个文本串,问从两个串中各取一个非空子串,使这俩子串相同,问方案有多少种.我的思路 ...
- BZOJ 4566: [Haoi2016]找相同字符 [后缀自动机]
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 275 Solved: 155[Submit][Statu ...
- bzoj 4566 [Haoi2016]找相同字符SA
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 128 Solved: 75[Submit][Status ...
- bzoj 4566 找相同字符 —— 广义后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4566 建出两个串的广义后缀自动机: 统计每个点在两个串中出现次数的子树和,其实就是在两个串中 ...
- ●BZOJ 4566 [Haoi2016]找相同字符
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4566题解: 广义后缀自动机 对两个串同时建立一个广义后缀自动机. 同时统计出每个状态对两个串 ...
- BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)
题目链接 给定两个字符串,求它们有多少个相同子串.相同串的位置不同算多个. POJ3145简化版. 后缀自动机做法见这儿,又快又好写(一下就看出差距了..) //13712kb 4076ms #inc ...
随机推荐
- 图片压缩(pc端和移动端都适用)
最近在做移动端遇到了一个问题就是: 手机拍照后,图片过大如果上传到服务器务必会浪费带宽,最重要的是流量啊 别慌,好事儿来了,务必就会有人去研究研究图片的压缩: 鄙人结合前人的经验,结合自己实战,总结出 ...
- vi 搜索
/ 向下搜索 ? 向上搜索 n 重复前一个搜索 N 反向重复前一个搜索
- 分析(ExtractTransformLoad)与挖掘(DataMine)有何区别 ?
首先,介绍一下ETL 和 DM: ETL/Extraction-Transformation-Loading——用于完成DB到DW的数据转存,它将DB中的某一个时间点的状态,“抽取”出来,根据 ...
- 关于sqlserver帐号被禁用问题
若发现sqlsrver所有帐号不小心被禁用了,这个时候怎么办?用重装吗?不用,仔细看小白是怎么一步一步解开这个谜题的.首先需要Windows帐号设置里重新添加一个新帐号.并将其添加到管理员组里面,然后 ...
- windows的cmd和git bash的常用命令
windows下使用git bash,使用的事linux下的命令,整理常用命令如下: windows下的命令 linux下的命令 命令的含义 cd e:\xx cd /e/xx 切换到xx目录 cd ...
- poj1338 Ugly Numbers 打表, 递推
题意:一个数的质因子能是2, 3, 5, 那么这个数是丑数. 思路: 打表或者递推. 打表: 若该数为丑数,那么一定能被2 或者3, 或者5 整除, 除完之后则为1. #include <ios ...
- 二分查找算法java
二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元 ...
- js正则函数match、exec、test、search、replace、split使用集合
match 方法 使用正则表达式模式对字符串执行查找,并将包含查找的结果作为数组返回. stringObj.match(rgExp) 参数 stringObj 必选项.对其进行查找的 String 对 ...
- iOS旋屏
横竖屏切换,视图乱了怎么办? 首先,我们必须了解一下下列4种状态,它们被用来描述设备旋转方向: UIInterfaceOrientationLandscapeLeft 向左,即HOME键在右 UIIn ...
- laravel的安装与启动
今天,我就来给大家分享下laravel的安装 https://pkg.phpcomposer.com 这是官网的中国镜像 第一步: 点链接进来执行下面的三条语句 执行完后,查看下当前目录底下有个 c ...