51nod 1286 三段子串 extkmp
来源:互联网 发布:拳皇2002um画质优化 编辑:程序博客网 时间:2024/05/21 14:58
题目:
http://www.51nod.com/onlineJudge/questionCode.html#problemId=1286¬iceId=310651
题意:
给定一个字符串S,找到另外一个字符串T,T既是S的前缀,也是S的后缀,并且在中间某个地方也出现一次,并且这三次出现不重合。求T最长的长度。
例如:S = “abababababa”,其中”aba”既是S的前缀,也是S的后缀,中间还出现了一次,并且同前缀后缀均不重合。所以输出”aba”的长度3。如果找不到一个符合条件的字符,输出0。
Input
输入字符串S。(1 <= L <= 1000000, L为S的长度)
Output
输出这个最长的子串的长度。
思路:
和HDU 4763基本一样,但是必须二分才能过
#include <bits/stdc++.h>using namespace std;const int N = 1000000 + 10;char ori[N];int Next[N];int a[N];void get_next(char *pat){ int len = strlen(pat); Next[0] = len; int k = 0; while(k + 1 < len && pat[k] == pat[k+1]) ++k; Next[1] = k; k = 1; for(int i = 2; pat[i]; i++) { if(i + Next[i-k] < k + Next[k]) Next[i] = Next[i-k]; else { int j = max(k + Next[k] - i, 0); while(i + j < len && pat[i+j] == pat[j]) ++j; Next[i] = j; k = i; } }}int main(){ scanf("%s", ori); get_next(ori); int len = strlen(ori); int k = 0; for(int i = len - len/3; i < len; i++) if(i + Next[i] == len) a[++k] = Next[i]; int ans = 0; for(int i = 0; ori[i]; i++) { int l = 1, r = k, tmp = 0; while(l <= r) { int mid = (l + r) >> 1; if(a[mid] > Next[i]) l = mid + 1; else if(0+a[mid]-1 < i && i+a[mid]-1 < len-a[mid] && len-a[mid] + Next[len-a[mid]] == len) tmp = a[mid], r = mid - 1; else l = mid + 1; } ans = max(ans, tmp); } printf("%d\n", ans); return 0;}
阅读全文
0 0
- 51nod 1286 三段子串 extkmp
- 51 nod 1286 1286 三段子串(exkmp)
- 51 nod1286三段子串
- 段子
- 段子
- 段子
- 段子
- 段子
- 段子
- HDU 4333 Revolving Digits extkmp
- HDU 4763 Theme Section extkmp
- 51nod 贪心入门之三 活动安排问题二
- 51nod 1391:01串
- 51NOD 非010串
- 51nod-1391 01串
- 51nod 1391 01串
- 51nod-1391:01串
- 51nod 1391 01串
- 【软件激活】Lightroom6软件及激活
- 读《编译原理》(英文版)第一章
- Newtonsoft.Json.Linq.JArray 转换成 List<T>
- 一张图看懂在北京买房不同贷款方式的差别
- 处理器管理-线程和管程
- 51nod 1286 三段子串 extkmp
- Oracle权限
- Search Insert Position &&Search in Rotated Sorted Array &&Search in Rotated Sorted Array II
- 广州二手房价分析与预测
- mui 返回并刷新
- Oracle用户
- 八皇后问题—回溯算法
- Replace Pioneer
- 二分法查找和普通查找