题链:

http://www.lydsy.com/JudgeOnline/problem.php?id=4566
题解:

广义后缀自动机
对两个串同时建立一个广义后缀自动机。
同时统计出每个状态对两个串分别的right集合大小right[*][0/1]
那么答案就是$$ANS=\sum_s right[s][0]×right[s][1]×(maxs[s]-maxs[parent[s]])$$

代码:

#include<bits/stdc++.h>
#define MAXN 200005
#define ll long long
using namespace std;
struct SAM{
int size;
int maxs[MAXN*6],trans[MAXN*6][26],parent[MAXN*6],right[MAXN*6][2];
SAM(){
memset(trans[0],0,sizeof(trans[0]));
size=0; Newnode(0,0);
}
int Newnode(int a,int b){
++size; maxs[size]=a;
memcpy(trans[size],trans[b],sizeof(trans[b]));
return size;
}
int Extend(int last,int x){
static int p,np,q,nq; p=last;
if(trans[p][x]&&maxs[p]+1==maxs[trans[p][x]]) return trans[p][x];
np=Newnode(maxs[p]+1,0);
for(;p&&!trans[p][x];p=parent[p]) trans[p][x]=np;
if(!p) parent[np]=1;
else{
q=trans[p][x];
if(maxs[p]+1!=maxs[q]){
nq=Newnode(maxs[p]+1,q);
parent[nq]=parent[q];
parent[q]=parent[np]=nq;
for(;p&&trans[p][x]==q;p=parent[p]) trans[p][x]=nq;
}
else parent[np]=q;
}
return np;
}
void Build(char *S){
static int last; last=1;
for(int i=0;S[i];i++) last=Extend(last,S[i]-'a');
}
ll Count(char *S,char *T,ll ans=0){
static int p,len,tmp[MAXN],order[MAXN*6];
len=max(strlen(S),strlen(T));
p=1; for(int i=0;S[i];i++) p=trans[p][S[i]-'a'],right[p][0]++;
p=1; for(int i=0;T[i];i++) p=trans[p][T[i]-'a'],right[p][1]++;
for(int i=1;i<=size;i++) tmp[maxs[i]]++;
for(int i=1;i<=len;i++) tmp[i]+=tmp[i-1];
for(int i=1;i<=size;i++) order[tmp[maxs[i]]--]=i;
//不同于单串的后缀自动机,因为存在父子关系但是maxs相同的状态,但是可以确定的是这种情况下,父亲标号一定大于儿子标号
for(int i=size;i;i--){
p=order[i];
right[parent[p]][0]+=right[p][0];
right[parent[p]][1]+=right[p][1];
}
for(int i=1;i<=size;i++)
ans+=1ll*(maxs[i]-maxs[parent[i]])*right[i][0]*right[i][1];
return ans;
}
}SUF;
int main(){
static char S[MAXN],T[MAXN];
scanf("%s%s",S,T);
SUF.Build(S);
SUF.Build(T);
printf("%lld\n",SUF.Count(S,T));
return 0;
}

  

●BZOJ 4566 [Haoi2016]找相同字符的更多相关文章

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

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

  2. bzoj 4566 [Haoi2016]找相同字符SA

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 128  Solved: 75[Submit][Status ...

  3. bzoj 4566 [Haoi2016]找相同字符——广义后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4566 每个后缀结尾处 ct[ ] = 1 ,按拓扑序 dp 一下就能求出 right 集合的 ...

  4. 【刷题】BZOJ 4566 [Haoi2016]找相同字符

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别为 ...

  5. bzoj 4566: [Haoi2016]找相同字符

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...

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

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

  7. BZOJ 4566 [Haoi2016]找相同字符 ——广义后缀自动机

    建立广义后缀自动机. 然后统计子树中的siz,需要分开统计 然后对(l[i]-l[fa[i]])*siz[i][0]*siz[i][1]求和即可. #include <cstdio> #i ...

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

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

  9. [Bzoj4566][Haoi2016]找相同字符(广义后缀自动机)

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

随机推荐

  1. C语言博客作业—数组

    一.PTA实验作业 题目1:简化的插入排序 1. 本题PTA提交列表 2. 设计思路 (1)定义n,number,i,j,temp; (2)输入n; (3)定义数组a[n+1]; //把所有的数都放入 ...

  2. 201621123060《JAVA程序设计》第十三周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户通过网 ...

  3. 【iOS】Swift GCD-上

    尽管Grand Central Dispatch(GCD)已经存在一段时间了,但并非每个人都知道怎么使用它.这是情有可原的,因为并发很棘手,而且GCD本身基于C的API在Swift世界中很刺眼. 在这 ...

  4. sqlserver之排序规则和ETL不支持sqlserverdatetime2的问题

    sqlserver的排序规则大概分为Windows 排序规则和 SQL Server 排序规则.数据在安装的时候,默认不设置会默认为SQL_Latin1_General_CP1_CI_AI.数据库在创 ...

  5. 构建微服务开发环境7————使用Github管理项目代码的版本

    [内容指引] 1.注册GitHub帐号: 2.下载Github Desktop客户端: 3.macOS安装Github Desktop客户端: 4.windows安装Github Desktop客户端 ...

  6. Oracle RAC环境下定位并杀掉最终阻塞的会话

    实验环境:Oracle RAC 11.2.0.4 (2节点) 1.模拟故障:会话被级联阻塞 2.常规方法:梳理找出最终阻塞会话 3.改进方法:立即找出最终阻塞会话 之前其实也写过一篇相关文章: 如何定 ...

  7. JAVA_SE基础——71.Random类制作随机验证码

    public class Demo5 { public static void main(String[] args) { char[] arr={'s','b','g','h','a','c'}; ...

  8. 微信接口(一)创建菜单&自动回复

    刚划拉完微信.做一个笔记这里的数据是写死的,还有一份是通过查询数据库进行自动回复,自定义菜单设置的.不过因为使用到数据库,最好在网站后台吧微信平台开发集成进去.所以代码较多就先不放了.有问题的地方请留 ...

  9. python基础—函数装饰器

    python基础-函数装饰器 1.什么是装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...

  10. Hibernate(三): org.hibernate.HibernateException: No CurrentSessionContext configured!

    Hibernate版本5.2.9 获取Session的方式是sessionFactory.getCurrentSession(); 比较老一些的版本使用的是sessionFactory.openSes ...