题意

给出两个字符串\(s\)和\(t\),设\(S\)为\(s\)的任意一个非空前缀,\(T\)为\(t\)的任意一个非空前缀,问\(S+T\)有多少种不同的可能。

Solution

看了一圈,感觉好像就我一个人写的\(kmp+hash+\)二分。

直接算好像不是很好算?先容斥一下,不同\(=\)总方案\(-\)相同。

显然总方案为两个字符串的长度的乘积,考虑相同的情况怎么算。

相同即两组\(S\)和\(T\)不同,但\(S+T\)本质相同的情况.

这个东西怎么算呢。。。。

(感觉看图会好理解一点

不难想到当上图框出来的地方相同,则两者同质。

先来看右边那个框,显然这个东西就是一个字符串里两个子串\([1,i],[j,k]\)相同。

左边这个框就是\(s\)的某个子串和\(t\)的前缀相同。

具体怎么算?

根据上图,设\(a_i\)为\(t\)的前缀\([1,i]\)在\(s\)里出现了几次,这个可以\(hash+\)二分算。

设\(b_i\)为符合\([1,j]=[i-j+1,i]\)的\(j\)的最大值,这个可以\(kmp\)一波。

那么最终同质的个数就是\(\sum_{i=2}^{|t|}a_{i-b_i}\)

#include<bits/stdc++.h>
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
#define cross(i,u) for (register int i=first[u];i;i=last[i])
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
inline ll read(){
ll x=0;int ch=getchar(),f=1;
while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
if (ch=='-'){f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int N = 1e5+10;
int n,m;
char a[N],b[N];
const ull base = 233;
ull pre[N],Pre[N],p[N];
const ll Base = 23, mod = 1e9+7;
ll pre2[N],Pre2[N],p2[N];
inline void GetPre(){
p[0]=1;For(i,1,n) p[i]=p[i-1]*base;
For(i,1,n) pre[i]=pre[i-1]*base+a[i];
For(i,1,m) Pre[i]=Pre[i-1]*base+b[i];
p2[0]=1;For(i,1,n) p2[i]=p2[i-1]*Base%mod;
For(i,1,n) (pre2[i]=pre2[i-1]*Base%mod+a[i])%=mod;
For(i,1,m) (Pre2[i]=Pre2[i-1]*Base%mod+b[i])%=mod;
}
inline ull query(int l,int r){return pre[r]-pre[l-1]*p[r-l+1];}
inline ll query2(int l,int r){return (pre2[r]-pre2[l-1]*p2[r-l+1]%mod+mod)%mod;}
int now,fail[N];
inline void GetKmp(){
now=0;
For(i,2,m){
while (now&&b[now+1]!=b[i]) now=fail[now];
fail[i]=(b[now+1]==b[i]?++now:now);
}
}
int sum[N];
inline void Get(){
For(i,2,n){
int l=1,r=min(m,n-i+1),mid,ans=0;
while (l<=r){
mid=l+r>>1;
if (query(i,i+mid-1)==Pre[mid]&&query2(i,i+mid-1)==Pre2[mid]) l=mid+1,ans=mid;
else r=mid-1;
}
sum[ans]++;
}
sum[0]=0;
Dow(i,m,1) sum[i]+=sum[i+1];
}
inline void calc(){
ll ans=1ll*n*m;
For(i,2,m) if (fail[i]) ans-=sum[i-fail[i]];
printf("%lld\n",ans);
}
int main(){
scanf("%s",a+1),scanf("%s",b+1),n=strlen(a+1),m=strlen(b+1);
GetPre(),GetKmp(),Get(),calc();
}

Codeforces 1090J $kmp+hash+$二分的更多相关文章

  1. [Codeforces 1199C]MP3(离散化+二分答案)

    [Codeforces 1199C]MP3(离散化+二分答案) 题面 给出一个长度为n的序列\(a_i\)和常数I,定义一次操作[l,r]可以把序列中<l的数全部变成l,>r的数全部变成r ...

  2. CodeForces 670D1 暴力或二分

    今天,开博客,,,激动,第一次啊 嗯,,先来发水题纪念一下 D1. Magic Powder - 1   This problem is given in two versions that diff ...

  3. codeforces 895B XK Segments 二分 思维

    codeforces 895B XK Segments 题目大意: 寻找符合要求的\((i,j)\)对,有:\[a_i \le a_j \] 同时存在\(k\),且\(k\)能够被\(x\)整除,\( ...

  4. Codeforces 626C Block Towers(二分)

    C. Block Towers time limit per test:2 seconds memory limit per test:256 megabytes input:standard inp ...

  5. codeforces 803D Magazine Ad(二分+贪心)

    Magazine Ad 题目链接:http://codeforces.com/contest/803/problem/D ——每天在线,欢迎留言谈论. 题目大意: 给你一个数字k,和一行字符 例: g ...

  6. Success Rate CodeForces - 807C (数学+二分)

    You are an experienced Codeforces user. Today you found out that during your activity on Codeforces ...

  7. Codeforces 1132D - Stressful Training - [二分+贪心+优先队列]

    题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有 $n$ 个学生,他们的电脑有初始电量 $a[1 \sim n]$,他们的电脑每分钟会耗 ...

  8. Codeforces 1114E - Arithmetic Progression - [二分+随机数]

    题目链接:http://codeforces.com/problemset/problem/1114/E 题意: 交互题,有一个 $n$ 个整数的打乱顺序后的等差数列 $a[1 \sim n]$,保证 ...

  9. Codeforces 660C - Hard Process - [二分+DP]

    题目链接:http://codeforces.com/problemset/problem/660/C 题意: 给你一个长度为 $n$ 的 $01$ 串 $a$,记 $f(a)$ 表示其中最长的一段连 ...

随机推荐

  1. 脚本病毒分析扫描专题2-Powershell代码阅读扫盲

    4.2.PowerShell 为了保障木马样本的体积很小利于传播.攻击者会借助宏->WMI->Powershell的方式下载可执行文件恶意代码.最近也经常会遇见利用Powershell通过 ...

  2. go 数组

    数组的定义和 初始化 数组是同一类型的元素集合 ]int //定义⼀个数组 Go中数组下标从0开始,因此长度为n的数组下标范围:[0,n-1] 整数数组中的元素默认初始化为0,字符串数组中的元素默认初 ...

  3. RW RO ZI ROM keil中的含义

    编译的一个ARM的程序,会得到这样的信息: ============================================================================== ...

  4. python 元组分组并排序

    # -*- coding: utf-8 -*- # @Time : 2018/8/31 14:32 # @Author : cxa # @File : glomtest.py # @Software: ...

  5. MyEclipse中Source not found的问题

    1.问题描述 在MyEclipse中想查看源码,结果显示:Source not found ......(大概的意思就是找不到源码包) 2.解决方案 下载相应版本的apache-tomcat-8.5. ...

  6. 链家2018春招C/C++开发实习生在线考试编程题

    题目一 题解:该题目意思就是让你输入n组数据,然后求并集,利用STL容器set集合的特性:元素不重复存储,我们可以很轻易得出答案 #include <iostream> #include ...

  7. kickstart配置LINUX无人值守选项--rootpw

    linux kickstart rootpw密码可以使用明文,也可以使用加密过的值(密码为:IPPBXADMINROOT) 注意:在这里要使用加密过的值,否则安全性就太低了 rootpw --iscr ...

  8. PHP性能调优---PHP调试工具Xdebug安装配置教程

    说到PHP代码调试,对于有经验的PHPer,通过echo.print_r.var_dump函数,或PHP开发工具zend studio.editplus可解决大部分问题,但是对于PHP入门学习的童鞋来 ...

  9. C++中memcpy和memmove

    二者都是内存拷贝 memcpy内存拷贝,没有问题;memmove,内存移动?错,如果这样理解的话,那么这篇文章你就必须要好好看看了,memmove还是内存拷贝.那么既然memcpy和memmove二者 ...

  10. USACO 6.5 All Latin Squares

    All Latin Squares A square arrangement of numbers 1 2 3 4 5 2 1 4 5 3 3 4 5 1 2 4 5 2 3 1 5 3 1 2 4 ...