1511: [POI2006]OKR-Periods of Words
2024-08-27 19:36:26
1511: [POI2006]OKR-Periods of Words
https://www.lydsy.com/JudgeOnline/problem.php?id=1511
题意:
对于一个串的所有前缀,设为s,求出它的最大前缀Q,使得s为QQ的前缀。求最大前缀长度的和。
分析:
KMP+next数组。
next数组表示的是这个字符串的最大的公共前缀后缀。对于字符串s,设其next为j,那么它的前j个和后j个是相等的。如果这j个没有重叠,那么所求的最长前缀就是1~n-j。把这个前缀重复两遍可以包含s。所求的就是最小的这样border,最小的j(j越小,相当于n个字符,后j个更少,那么剩余的所求的前缀就越长了)。然后求出最小的公共前后缀。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL; 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;
} const int N = ; char A[N];
int p[N]; int main() {
int n; cin >> n;
scanf("%s",A+);
p[] = ;
for (int i=; i<=n; ++i) {
int j = p[i-];
while (j && A[i]!=A[j+]) j = p[j];
if (A[i] == A[j+]) j++;
p[i] = j;
}
LL ans = ;
for (int i=; i<=n; ++i) {
int j = i;
while (p[j]) j = p[j]; // 这里看到这样写的p[p[j]],其实每个p[i]在下面已经更新了,不需要跳很多次。
if (p[i] != ) p[i] = j; // 类似于记忆化,前缀i的跳的最优位置。
ans += i - j;
}
cout << ans;
return ;
}
最新文章
- 设计模式(十三) 职责链(chain of responsibility)
- 【转】Web测试方法
- Html5 布局方式
- ubuntu/mint 安装google的拼音输入法
- 自动化(Automation)兼容的数据类型
- Java 反射机制及Annotation
- C++从键盘输入文件结束符
- 【BZOJ】【1017】【JSOI2008】魔兽地图Dotr
- ARM指令协处理器处理指令
- 怎样把SEL放进NSArray里
- 微信企业号 jsSDK wx.config报invalid signature错误,导致api接口无法使用
- nginx源代码学习资源(不断更新)
- Android自定义View之音频条形图
- 六星经典CSAPP笔记(2)信息的操作和表示
- initWithFrame方法的使用
- Groovy与Java集成常见的坑
- HDU 4391 Paint The Wall(分块的区间维护)
- linux基本之一
- 查看SQL实际内存占用
- (转)在 WebSphere Application Server 中修改主机名称并迁移概要文件
热门文章
- Echarts横坐标倾斜,顶部显示数字
- 【[SCOI2009]粉刷匠】
- PHP设计模式——装饰器模式
- ASP.NET Web API 自定义MediaType实现jsonp跨域调用
- ImageNet Classification with Deep Convolutional Nerual Networks(AlexNet)
- java实现权重随机算法
- SpringMVC学习记录五——功能开发及参数处理
- 【luogu P3371 单源最短路径】 模板 dij + heap
- Entity Framework 一
- 大学C++程序设计教程期末复习重点