【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 ...
随机推荐
- jquery最常用的几个方法。——可删除
jquery使用手册:http://www.eduyo.com/doc/jquery/cheatsheet.html $(this).hasClass("input_money") ...
- stringstream clear与str("")的问题
一.str与clear函数 C++Reference对于两者的解释: 可见:clear()用来设置错误状态,相当于状态的重置:str用来获取或预置内容 二.区别 运行下面测试代码: #include& ...
- 讲课笔记1——meta标签、表格标签
图片属性:src(source): 图片的来源(路径),可以放置本地图片,也可以放网上的图片的url地址 [相对路径: ./:当前目录 ../:跳出当前目录,到上一 ...
- 关于bootstrap栅格系统的五等分以及八等分代码
众所周知,bootstrap的栅格系统是基于十二等分的,今天拿到设计的设计稿一看,发现一个图片list上只有8张图片,然后上网查资料,发现只能自己写css代码实现,故写博客记录代码. 以下是八等分的代 ...
- Hermite 矩阵及其特征刻画
将学习到什么 矩阵 \(A\) 与 \(\dfrac{1}{2}(A+A^T)\) 两者生成相同的二次型,而后面那个矩阵是对称的,这样以来,为了研究实的或者复的二次型,就只需要研究由对称矩阵生成的二次 ...
- linx vim 文件操作 ubuntu server 软件源
mv /etc/danted.conf /etc/danted.conf.bak sudo wget https://files.cnblogs.com/files/marklove/danted.t ...
- httpClient类
@SuppressWarnings("finally") public JSONObject doPost(String url, String parms){ if (" ...
- Spring框架针对dao层的jdbcTemplate操作crud之query查询数据操作 —— 查询表,返回结果为对象的list集合
用JdbcTemplate的方法完成, 查询数据库表,把用户表sw_user所有数据以List<User>集合返回 在JdbcTemplateDemo类中增加查询返回所有对象集合的方法qu ...
- 006 CSS三种引入方式
CSS三种引入方式 一.三种方式的书写规范 1.行间式 <div style="width: 100px; height: 100px; background-color: red&q ...
- mysql中常用函数简介(不定时更新)
常用函数version() 显示当前数据库版本database() 返回当前数据库名称user() 返回当前登录用户名inet_aton(IP) 返回IP地址的数值形式,为IP地址的数学计算做准备in ...