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 ;
}

最新文章

  1. 设计模式(十三) 职责链(chain of responsibility)
  2. 【转】Web测试方法
  3. Html5 布局方式
  4. ubuntu/mint 安装google的拼音输入法
  5. 自动化(Automation)兼容的数据类型
  6. Java 反射机制及Annotation
  7. C++从键盘输入文件结束符
  8. 【BZOJ】【1017】【JSOI2008】魔兽地图Dotr
  9. ARM指令协处理器处理指令
  10. 怎样把SEL放进NSArray里
  11. 微信企业号 jsSDK wx.config报invalid signature错误,导致api接口无法使用
  12. nginx源代码学习资源(不断更新)
  13. Android自定义View之音频条形图
  14. 六星经典CSAPP笔记(2)信息的操作和表示
  15. initWithFrame方法的使用
  16. Groovy与Java集成常见的坑
  17. HDU 4391 Paint The Wall(分块的区间维护)
  18. linux基本之一
  19. 查看SQL实际内存占用
  20. (转)在 WebSphere Application Server 中修改主机名称并迁移概要文件

热门文章

  1. Echarts横坐标倾斜,顶部显示数字
  2. 【[SCOI2009]粉刷匠】
  3. PHP设计模式——装饰器模式
  4. ASP.NET Web API 自定义MediaType实现jsonp跨域调用
  5. ImageNet Classification with Deep Convolutional Nerual Networks(AlexNet)
  6. java实现权重随机算法
  7. SpringMVC学习记录五——功能开发及参数处理
  8. 【luogu P3371 单源最短路径】 模板 dij + heap
  9. Entity Framework 一
  10. 大学C++程序设计教程期末复习重点