学习了一下这个较为冷门的知识,由于从日报开始看起,还是比较绕的……

首先定义 \(Z\) 函数表示后缀 \(i\) 与整个串的 \(lcp\) 长度

一个比较好的理解于实现方式是类似于 \(manacher\) 维护出 \([l,r]\) 表示能够匹配的最右端是 \(l\) 位置匹配上的到达 \(r\) 的区间

假设目前求到 \(i\):

那么可以发现可以直接由 \(nxt[i-l+1]\) 继承过来,需要和 \(r-i+1\) 取 \(min\)

另一个问题是假如 \(r<i\) 或 \(nxt[i-l+1]\ge r-i+1\),后面的部分需要进行暴力匹配

并且及时更新 \(r\) 的取值

以下是模板实现:

代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e7+5;
int n,m,nxt[maxn],ex[maxn];
char a[maxn],b[maxn];
long long ans;
void getnxt(){
nxt[1]=m;
for(int i=2,l=0,r=0;i<=m;i++){
if(i<=r)nxt[i]=min(nxt[i-l+1],r-i+1);
while(i+nxt[i]<=m&&b[nxt[i]+i]==b[nxt[i]+1])nxt[i]++;
if(i+nxt[i]-1>r)r=i+nxt[i]-1,l=i;
}
return ;
}
void exkmp(){
for(int i=1,l=0,r=0;i<=n;i++){
if(i<=r)ex[i]=min(nxt[i-l+1],r-i+1);
while(i+ex[i]<=n&&a[ex[i]+i]==b[ex[i]+1])ex[i]++;
if(i+ex[i]-1>r)l=i,r=i+ex[i]-1;
}
return ;
}
int main(){
scanf("%s%s",a+1,b+1);
n=strlen(a+1),m=strlen(b+1);
getnxt();exkmp();
for(int i=1;i<=m;i++)ans^=1ll*i*(nxt[i]+1);cout<<ans<<endl;//printf("%d ",nxt[i]);puts("");
ans=0;for(int i=1;i<=n;i++)ans^=1ll*i*(ex[i]+1);cout<<ans;
return 0;
}

CF432D Prefixes and Suffixes

相当于比较每个后缀的 \(nxt\) 值是否等于后缀长度

由于需要求出现的次数,不妨还是把后缀们平移到前缀的位置

那么发现一个前缀出现的次数是后面前缀出现次数的前缀和

代码实现
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
char a[maxn];
int nxt[maxn],ans,cnt[maxn];
bool vis[maxn];
int main(){
scanf("%s",a+1);
int n=strlen(a+1);
nxt[1]=n;
for(int i=2,l=0,r=0;i<=n;i++){
if(i<=r)nxt[i]=min(nxt[i-l+1],r-i+1);
while(nxt[i]+i<=n&&a[nxt[i]+i]==a[nxt[i]+1])nxt[i]++;
if(nxt[i]+i-1>r)r=nxt[i]+i-1,l=i;
}
for(int i=1;i<=n;i++){
if(i+nxt[i]-1==n)ans++,vis[nxt[i]]=true;
cnt[nxt[i]]++;
}
for(int i=n;i>=1;i--)cnt[i]+=cnt[i+1];
cout<<ans<<endl;
for(int i=1;i<=n;i++)if(vis[i])printf("%d %d\n",i,cnt[i]);
return 0;
}

扩展kmp 学习笔记的更多相关文章

  1. 扩展kmp学习笔记

    kmp没写过,扩展kmp没学过可还行. 两个愿望,一次满足 (该博客仅用于防止自己忘记,不保证初学者能看懂我在瞎bb什么qwq) 用途 对于串\(s1,s2\),可以求出\(s2\)与\(s1\)的每 ...

  2. 126B Password[扩展kmp学习]

    题目大意 给你一个字符串,求它的一个子串使得这个子串即使前缀又是后缀又出现在不是前缀且不是后缀的地方 分析 扩展kmp就是定义z[i]表示i~n的子串与整个串的最长公共前缀的长度是z[i] 所以这个题 ...

  3. KMP学习笔记

    功能 字符串T,长度为n. 模板串P,长度为m.在字符串T中找到匹配点i,使得从i开始T[i]=P[0], T[i+1]=P[1], . . . , T[i+m-1]=P[m-1] KMP算法先用O( ...

  4. C#扩展方法学习笔记

    C#扩展方法,简单的理解是不修改原来类的源代码的情况下,为某个类添加某个方法.扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的.它们的第一个参数指定该方法作用于哪个类型,并且该参数以 th ...

  5. Unity扩展编辑器学习笔记--从路径下找到拥有某个组件类型的预设

    public static List<T> GetAssetsWithScript<T>(string path) where T:MonoBehaviour { T tmp; ...

  6. ReactiveX 学习笔记(0)学习资源

    ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...

  7. Kuangbin 带你飞 KMP扩展KMP Manacher

    首先是几份模版 KMP void kmp_pre(char x[],int m,int fail[]) { int i,j; j = fail[] = -; i = ; while (i < m ...

  8. Kotlin学习笔记(9)- 数据类

    系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正.如果你觉得我的文章对你有用,欢迎关注我,我们一起学习进步! Kotlin学习笔记(1)- 环境配置 Kotlin学习笔记(2)- 空安 ...

  9. HDU 4333 Revolving Digits [扩展KMP]【学习笔记】

    题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如 ...

随机推荐

  1. Veritas Backup Exec™ 21.3 Multilingual (Windows)

    Backup Exec 21.3, Release date: 2021-09-06 请访问原文链接:https://sysin.org/blog/veritas-backup-exec-21-3/, ...

  2. 树行DP小结

    顾名思义:就是在树上做的DP,依据DFS的性质,在访问过儿子之后返回后将儿子的状态传递给父亲... 先看例题: 此题用贪心也能过,不过正解是DP. 对于树上的DP我们可以直接考虑最优解下各点的状态来方 ...

  3. SpringCloud微服务实战——搭建企业级开发框架(十三):OpenFeign+Ribbon实现高可用重试机制

      Spring Cloud OpenFeign 默认是使用Ribbon实现负载均衡和重试机制的,虽然Feign有自己的重试机制,但该功能在Spring Cloud OpenFeign基本用不上,除非 ...

  4. hadoop前期准备

    最近想要学习一下hadoop,现在想边学习边记录下,方便以后自己或别人查看.(注意最好ubantu,jdk及其他软件选择32bit的,jdk最好7以上) 首先配置下jdk,下载下jdk的包,把jdk- ...

  5. 记一次线上环境 ES 主分片为分配故障

    故障前提 ElasticSearch 版本:5.2 集群节点数:5 索引主分片数:5 索引分片副本数:1 线上环境ES存储的数据量很大,当天由于存储故障,导致一时间 5个节点的 ES 集群,同时有两个 ...

  6. [mysql课程作业]我的大学|作业

    第八周周五 1.将xs表中王元的专业改为"智能建筑". # update xs set 专业名='智能建筑' where 姓名='王元'; # select * from xs w ...

  7. java中的泛型设计

    1.为什么要使用泛型程序设计 ArrayList<String> files = new ArrayList<>() 等价于 var files = new ArrayList ...

  8. Oracle SQL注入 总结

    0x00 Oracle基础 Oracle 基本使用 什么是Oracle数据库? Oracle公司目前是世界上最大的软件提供商之一,与它并列的还有 Microsoft与 Adode.并且随着 Oracl ...

  9. 组件通过props属性传值

    组件之间的传值 组件是一个单独功能模块的封装,有属于自己的data和methods,一个组件的 data 选项必须是一个函数 为什么必须是函数:因为只有当data是函数时,不同实例调用同一个组件时才会 ...

  10. restTemple发送请求、上传文件(@LoadBalanced微服务调用及url调用)

    import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Co ...