【kmp或扩展kmp】HDU 6153 A Secret
acm.hdu.edu.cn/showproblem.php?pid=6153
【题意】
- 给定字符串A和B,求B的所有后缀在A中出现次数与其长度的乘积之和
- A和B的长度最大为1e6
方法一:扩展kmp
【思路】
- 把A和B同时反转,相当于求B的所有前缀在A中出现次数与其长度的乘积之和
- 换个角度,相当于A中每出现一个B的前缀,答案中就要加上该前缀的长度
- 考虑A中每个位置对答案的贡献,A[i...lenA-1]与B的最长公共前缀是x,则B中的前缀B[0...1],B[0....2]...B[0....x]都在A中出现,那么答案就要加上x*(x+1)/2
- 求S中的每个后缀与T的最长公共前缀用扩展KMP,时间复杂度是线性的
【AC】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+;
const int maxn=1e6+;
char s[maxn];
char t[maxn];
int nxt[maxn];
int extend[maxn];
ll ans; void add(ll n)
{
ll tmp=((n%mod)*((n+)%mod)/)%mod;
ans=(ans+tmp)%mod;
}
void pre_EKMP(char x[],int m,int nxt[])
{
nxt[]=m;
int j=;
while(j+<m && x[j]==x[j+]) j++;
nxt[]=j;
int k=;
for(int i=;i<m;i++)
{
int p=nxt[k]+k-;
int L=nxt[i-k];
if(i+L<p+) nxt[i]=L;
else
{
j=max(,p-i+);
while(i+j<m && x[i+j]==x[j]) j++;
nxt[i]=j;
k=i;
}
}
} void EKMP(char x[],int m,char y[],int n,int nxt[],int extend[])
{
pre_EKMP(x,m,nxt);//子串
int j=;
while(j<n && j<m &&x[j]==y[j]) j++;
extend[]=j;
int k=;
for(int i=;i<n;i++)
{
int p=extend[k]+k-;
int L=nxt[i-k];
if(i+L<p+) extend[i]=L;
else
{
j=max(,p-i+);
while(i+j<n && j<m && y[i+j]==x[j]) j++;
extend[i]=j;
k=i;
}
}
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
scanf("%s",t);
int ls=strlen(s);
int lt=strlen(t);
for(int i=;i<ls/;i++)
{
swap(s[i],s[ls--i]);
}
for(int i=;i<lt/;i++)
{
swap(t[i],t[lt--i]);
}
EKMP(t,lt,s,ls,nxt,extend);
ans=;
for(int i=;i<ls;i++)
{
add(extend[i]);
}
printf("%I64d\n",ans);
}
return ;
}
扩展kmp
方法二:巧用kmp的next数组
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+;
ll id[maxn];
char s[maxn];
char t[maxn];
int nxt[maxn];
const ll mod=1e9+;
void kmp_pre(char x[],int m,int nxt[])
{
int i,j;
j=nxt[]=-;
i=;
while(i<m)
{
while(-!=j && x[i]!=x[j]) j=nxt[j];
nxt[++i]=++j;
}
} int kmp_count(char x[],int m,char y[],int n)
{
memset(id,,sizeof(id));
int i,j;
ll ans=;
kmp_pre(x,m,nxt);
i=j=;
while(i<n)
{
while(-!=j && y[i]!=x[j])
j=nxt[j];
i++;
j++;
if(i>=n) break;
//失配时记录当前匹配的最长前缀
if(y[i]!=x[j])
{
id[j]++;
}
if(j>=m)
j=nxt[j];
}
//s的结尾出有一段和匹配的,由于i已经达到n没有记录,用t本身的nxt算出
while(j!=-)
{
id[j]++;
j=nxt[j];
}
for(int i=;i<=m;i++)
{
if(id[i])
{
ans=(ans+(1ll*i*(i+)/)%mod*id[i]%mod)%mod;
}
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
scanf("%s",t);
int ls=strlen(s);
int lt=strlen(t);
reverse(s,s+ls);
reverse(t,t+lt);
ll res=kmp_count(t,lt,s,ls);
cout<<res<<endl;
}
return ;
}
kmp
【kmp或扩展kmp】HDU 6153 A Secret的更多相关文章
- KMP && Manacher && 扩展KMP整理
KMP算法: kmp示例代码: void cal_next(char *str, int *next, int len) { next[0] = -1;//next[0]初始化为-1,-1表示不存在相 ...
- KMP和扩展KMP【转】
这种东西基本上在纸上自己推导一下就能做出来XD 转发注明出处 KMP 给出两个字符串A(称为模板串)和B(称为子串),长度分别为lenA和lenB,要求在线性时间内,对于每个A[i] (0<=i ...
- KMP与扩展KMP
原文转自:http://www.cppblog.com/MatoNo1/archive/2011/04/17/144390.aspx KMP:给出两个字符串A(称为模板串)和B(称为子串),长度分别为 ...
- Manacher模板,kmp,扩展kmp,最小表示法模板
*N]; //储存临时串 *N];//中间记录 int Manacher(char tmp[]) { int len=strlen(tmp); ; ;i<len;i++) { s[cnt++]= ...
- HDU 6153 A Secret(扩展KMP模板题)
A Secret Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others) Total ...
- HDU 6153 A Secret(扩展kmp)
A Secret Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others)Total ...
- KMP和扩展KMP
文章网上太多这里提一下代码细节: KMP: scanf("%s\n",s); scanf("%s\n",t); int ls=strlen(s),lt=strl ...
- kmp模板 && 扩展kmp模板
kmp模板: #include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; ...
- KMP 、扩展KMP、Manacher算法 总结
一. KMP 1 找字符串x是否存在于y串中,或者存在了几次 HDU1711 Number Sequence HDU1686 Oulipo HDU2087 剪花布条 2.求多个字符串的最长公共子串 P ...
随机推荐
- hdu 3555 Bomb 炸弹(数位DP,入门)
题意: 给一个数字n,求从1~n中有多少个数是含有49的,比如49,149,1490等都是含49的. 思路: 2^64也顶多是十进制的20多位,那么按十进制位来分析更简单.如果能计算k位十进制数中分别 ...
- Adding other views to UIButton
Q: I want to add some views to UIButton, for example multiple UILabels, UIImages etc. One I add thos ...
- strongSwan大坑一直重启(ubuntu)
报错 Starting strongSwan 5.3.2 IPsec [starter]... charon (20533) started after 40 ms charon stopped af ...
- App Store中的开源游戏汇总
这是国外达人收集的曾经在app store上出现过,或者还在app store上卖的iOS开源游戏的列表,其中代码大部分人你托管在google code或者github上,其中有很多使用Cocos2D ...
- 单源最短路SPFA
#include<iostream> #include<queue> #include<cstring> #define INF 0x3f3f3f3f using ...
- 产生式模型(生成式模型)与判别式模型<转载>
转自http://dongzipnf.blog.sohu.com/189983746.html 产生式模型与判别式模型 产生式模型(Generative Model)与判别式模型(Discrimiti ...
- java项目指向maven进行构建方式
1.在需要运行的机器中环境变量中配置maven 运行setting 4 配置环境变量 2.运行项目进行重新构建:alt+F5
- 低性能3张图片轮播React组件
import React from 'react'; import {getSwipeWay} from '../utils/swipe'; class Carousel extends React. ...
- React框架搭建单页面应用package.json基本包和依赖包
{ //依赖包 "devDependencies": { //babel "babel-core": "6.24.1", "bab ...
- C\C++对于字符串输入处理
1.scanf scanf以%s格式符读入字符串,会以空格为结束,也就是无法将空格读入.如果换成%c就可以读入,但是无法一次性读入一整行字符. 2.fgets 显然,fgets是一个读取带空格字符串的 ...