4566: [Haoi2016]找相同字符

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 1212  Solved: 694
[Submit][Status][Discuss]

Description

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

Input

两行,两个字符串s1,s2,长度分别为n1,n2。1 <=n1, n2<= 200000,字符串中只有小写字母

Output

输出一个整数表示答案

Sample Input

aabb
bbaa

Sample Output

10

HINT

 

Source

时隔许久后重新获得了后缀自动机技能。

 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstdio>
#define maxn 200005
#define ll long long
using namespace std;
inline int read() {
int x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
struct SUF {
int sz[maxn*],link[maxn*],step[maxn*],son[maxn*][],v[maxn*],pos[maxn*];
int nxt[maxn*],head[maxn*],tto[maxn*],tot;
int cnt,last;
SUF() {last=cnt=;memset(head,-,sizeof(head));}
void extend(int c) {
int p=last,np=last=++cnt;step[np]=step[p]+;sz[np]=;
while(p&&!son[p][c]) son[p][c]=np,p=link[p];
if(!p) link[np]=;
else {
int q=son[p][c];
if(step[q]==step[p]+) link[np]=q;
else {
int nq=++cnt;
memcpy(son[nq],son[q],sizeof(son[q]));
link[nq]=link[q];link[q]=link[np]=nq;
step[nq]=step[p]+;
while(son[p][c]==q&&p) son[p][c]=nq,p=link[p];
}
}
}
void pre() {
for(int i=;i<=cnt;i++) v[step[i]]++;
for(int i=;i<=cnt;i++) v[i]+=v[i-];
for(int i=cnt;i>=;i--) pos[v[step[i]]--]=i;
for(int i=cnt;i>=;i--) sz[link[pos[i]]]+=sz[pos[i]];
}
ll f[maxn*];
void dfs(int x) {
f[x]+=1ll*sz[x]*(step[x]-step[link[x]]);
for(int i=head[x];i>=;i=nxt[i]) {
int to=tto[i];f[to]+=f[x];dfs(to);
}
}
void add(int u,int v) {
nxt[tot]=head[u];tto[tot]=v;head[u]=tot++;
}
}t;
char ch[maxn];
int main() {
scanf("%s",ch+);int len=strlen(ch+);
for(int i=;i<=len;i++) t.extend(ch[i]-'a');
t.pre();
scanf("%s",ch+);len=strlen(ch+);
for(int i=;i<=t.cnt;i++) if(t.link[i]) t.add(t.link[i],i);t.dfs();
int now=,l=;ll ans=;
for(int i=;i<=len;i++) {
int to=ch[i]-'a';
while(now&&!t.son[now][to]) now=t.link[now];
if(!now) now=,l=;
else l=min(l,t.step[now])+,now=t.son[now][to];
ans+=t.f[t.link[now]];ans+=1ll*(l-t.step[t.link[now]])*t.sz[now];
}
printf("%lld\n",ans);
}

[BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp的更多相关文章

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

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

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

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

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

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

  4. BZOJ4566 [Haoi2016]找相同字符【SAM】

    BZOJ4566 [Haoi2016]找相同字符 给定两个字符串\(s和t\),要求找出两个字符串中所有可以相互匹配的子串对的数量 首先考虑可以怎么做,我们可以枚举\(t\)串的前缀\(t'\),然后 ...

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

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

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

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

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

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

  8. BZOJ4566 Haoi2016 找相同字符【广义后缀自动机】

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

  9. [HAOI2016]找相同字符(SAM+DP)

    感觉很水. 因为SAM上一个点的子树大小代表这个点所表示子串的出现次数. 建出广义后缀自动机之后.在\(parent\)树上跑\(DP\),维护\(size[i][1]\),和\(size[i][0] ...

随机推荐

  1. Codeforces Round #342 (Div. 2) B

    B. War of the Corporations time limit per test 1 second memory limit per test 256 megabytes input st ...

  2. Rectangle 暴力枚举大法

    frog has a piece of paper divided into n rows and m columns. Today, she would like to draw a rectang ...

  3. Qt ------ 内存回收机制、new对象的回收

    写在前面的总结: 建议:对于不能指定父对象的对象(对象通过moveToThread()移入其他线程.没有继承QObject的类产生的对象),在其他线程通过deleteLater()内存回收,其他通过指 ...

  4. Bigbluebutton安装过程

    BigBlueButton安装过程(翻译) 欢迎来到BigBlueButton 1.0-beta安装指南(以下简称BigBlueButton 1.0).BigBlueButton是一个开放源代码的网络 ...

  5. liunx环境下安装mysql数据库2

    mysql的安装和配置[1]解压mysql安装包,进入mysql目录,添加用户,并安装,将权限授权给mysql用户

  6. javascript如何判断对象为空

    1.自定义jQuery的isEmptyObject()方法. function isEmptyObject(e) { var t; for (t in e) return !1; return !0 ...

  7. 使用jquery.qrcode生成二维码及常见问题解决方案

    转载文章  使用jquery.qrcode生成二维码及常见问题解决方案 一.jquery.qrcode.js介 jquery.qrcode.js 是一个纯浏览器 生成 QRcode 的 jQuery ...

  8. 数据结构&字符串:字典树

    前缀树里面可以存一堆字符串,也可以说是一堆单词,存完之后我们可以轻松判断一个指定的字符串是否出现过 下面我来详细解释一下实现细节 *+; //单词个数*每一个单词的字符数 ; struct Trie ...

  9. 【C++对象模型】第四章 Function 语意学

    1.Member的各种调用方式 1.1 Nonstatic Member Functions 实际上编译器是将member function被内化为nonmember的形式,经过下面转化步骤: 1.给 ...

  10. Java迭代实现斐波那契数列

    剑指offer第九题Java实现 题目: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项. public class Test9 { public static void ...