BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机)
BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机)
题面
自己找去
HINT
给定两个文本串,问从两个串中各取一个非空子串,使这俩子串相同,问方案有多少种。我的思路是建立一个广义后缀自动机,对于每个节点记录\(size[1]和size[2]\)分别表示这个节点接受的子串在A中出现多少次,在B中出现多少次,然后\(ans=\sum_{u=2}^{tot}{size[u][1]*size[u][2]*(node[u].len-node[fa].len)}\)注意要long long
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int w=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
w=(w<<3)+(w<<1)+ch-48;
ch=getchar();
}
return w*f;
}
int n,m;
int size[800010][3];
struct SUFFIXAUTOMATON{
struct Node{
int fa,len;
map<int,int> ch;
}node[800010];
int lst,tot,root;
inline void init(){
lst=tot=root=1;return;
}
inline void extend(int now,int id){
int p=lst;tot++;lst=tot;int np=tot;
node[np].len=node[p].len+1;size[np][id]=1;
while(p&&!node[p].ch[now]){
node[p].ch[now]=np;
p=node[p].fa;
}
if(!p) node[np].fa=1;
else{
int q=node[p].ch[now];
if(node[q].len==node[p].len+1){
node[np].fa=q;
}
else{
int nq=++tot;node[nq]=node[q];
node[nq].len=node[p].len+1;
node[q].fa=nq;node[np].fa=nq;
while(p&&node[p].ch[now]==q){
node[p].ch[now]=nq;
p=node[p].fa;
}
}
}
}
}SAM;
int cnt,head[800010];
struct Edge{
int from,to,next;
}edge[1600010];
inline void addedge(int u,int v){
cnt++;
edge[cnt].from=u;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
}
char ch[200010];
inline void dfs(int u){
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;dfs(v);
size[u][1]+=(long long)size[v][1];
size[u][2]+=(long long)size[v][2];
}
return;
}
long long ans;
signed main(){
SAM.init();
for(int i=1;i<=2;i++){
cin>>ch;int len=strlen(ch);
for(int j=0;j<len;j++){
SAM.extend(ch[j]-'a'+1,i);
}
SAM.lst=1;
}
for(int i=2;i<=SAM.tot;i++){
addedge(SAM.node[i].fa,i);
}
dfs(1);
//cout<<SAM.tot<<endl;
for(int i=2;i<=SAM.tot;i++){
int f=SAM.node[i].fa;
//cout<<(long long)size[i][1]*size[i][2]<<" "<<SAM.node[i].len-SAM.node[f].len<<endl;
long long cur1=(long long)size[i][1]*size[i][2];long long cur2=(long long)SAM.node[i].len-SAM.node[f].len;
//cout<<cur1<<" "<<cur2<<endl;
ans+=(long long)cur1*cur2;
}
cout<<ans<<endl;
return 0;
}
BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机)的更多相关文章
- [HAOI2016]找相同字符 广义后缀自动机_统计出现次数
题目描述:给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 输入输出格式输入格式:两行,两个字符串 s1,s2,长度分别为n ...
- bzoj 4566 找相同字符 —— 广义后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4566 建出两个串的广义后缀自动机: 统计每个点在两个串中出现次数的子树和,其实就是在两个串中 ...
- BZOJ 4566 [Haoi2016]找相同字符 ——广义后缀自动机
建立广义后缀自动机. 然后统计子树中的siz,需要分开统计 然后对(l[i]-l[fa[i]])*siz[i][0]*siz[i][1]求和即可. #include <cstdio> #i ...
- bzoj 4566 [Haoi2016]找相同字符——广义后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4566 每个后缀结尾处 ct[ ] = 1 ,按拓扑序 dp 一下就能求出 right 集合的 ...
- 【BZOJ4566】找相同字符(后缀自动机)
[BZOJ4566]找相同字符(后缀自动机) 题面 BZOJ 题解 看到多串处理,\(SA\)就连起来 \(SAM???\) 单串建自动机 然后其他串匹配 对于一个串建完\(SAM\)后 另一个串在\ ...
- BZOJ_4566_[Haoi2016]找相同字符_后缀自动机
BZOJ_4566_[Haoi2016]找相同字符_后缀自动机 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有 ...
- 【BZOJ4566】找相同字符【后缀自动机】
题意 给定两个字符串,求两个字符串相同子串的方案数. 分析 那么将字符串s1建SAM,然后对于s2的每个前缀,都在SAM中找出来,并且计数就行. 我一开始的做法是,建一个u和len,顺着s2跑SAM, ...
- BZOJ4566 HAOI2016找相同字符(后缀自动机)
对第一个串建SAM,第二个串在上面跑,记录当前前缀匹配的最长后缀长度l,每次考虑当前前缀的贡献,对于当前所在节点显然是|right|*(l-len[fa]),而对于其parent树上所有祖先的贡献显然 ...
- POJ3294Life Forms(广义后缀自动机)(后缀数组+二分+数状数组)
You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial ...
随机推荐
- Kafka中数据的流向
1: 多个消费者消费同一个Topic数据相同的数据 2: 多个消费者消费同一个Topic数据不同数据 3: 各个消费者按组协调消费 1: 多个消费者消费同一个Topic数据相同的数据 (1)使用一个全 ...
- 《自拍教程16》cmd的常用技巧
cmd.exe是Windows 自带的命令行操作交互界面软件. 虽然功能有限,但是毕竟是默认的命令行操作交互界面软件. 肯定所有的电脑都是自带的. 当然现在已经有很多改良版的,交互体验更好的cmd类似 ...
- monkey命令行测试
一. 什么是Monkey monkey是google提供的一个用于稳定性与压力测试的命令行工具.monkey程序由android系统自带,位于/sdcard/system/framework/monk ...
- [MacOS]MacOS字体文件位置
$ cd /System/Library/Fonts $ ls Apple Braille Outline 6 Dot.ttf Noteworthy.ttc SFCompactText-Regular ...
- 【全集】大数据Linux基础
课程介绍 本课程是由猎豹移动大数据架构师,根据公司大数据平台的运维情况,精心设计和打磨的大数据必备Linux课程.通过本课程的学习大数据新手能够少走弯路,快速掌握Linux常用命令及Shell编程,为 ...
- 珠峰-node
##### 文件流的读写. ##### 文件流对pipe的封装. ####
- Error serializing object:序列化对象时出错
序列化对象时出错 :Error serializing object. Error serializing object. Cause: java.io.NotSerializableExceptio ...
- Linux下通过二进制方式安装mysql5.7版本和系统优化
本文主要介绍MySQL二进制软件包的安装/启动/关闭过程. 也许有人要问为什么要选择二进制的安装方式呢? 其实答案很简单,官方版本中已经把所有功能都配置好了,我们可以很方便地拿来使用. 官方MySQL ...
- C# 一个帮您理解回调函数的例子(新手必看)
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 回调函数 ...
- RedHat7安装NetCore环境并发布网站
RedHat7安装NetCore环境并发布网站 1.注册Microsoft签名密钥并添加Microsoft产品提要,每台机器只需注册一次 执行下面的命令即可 rpm -Uvh https://pack ...