题意:

给定一个字符串S,找到另外一个字符串T,T既是S的前缀,也是S的后缀,并且在中间某个地方也出现一次,并且这三次出现不重合。求T最长的长度。

例如:S = "abababababa",其中"aba"既是S的前缀,也是S的后缀,中间还出现了一次,并且同前缀后缀均不重合。所以输出"aba"的长度3。如果找不到一个符合条件的字符,输出0。
 
题解:
先对S做一次拓展kmp,求出next数组
然后其实next每一个数就对应了一个前缀匹配的情况。
比如说next[3]和next[5]都为2,就意味着前缀为2的子串可以和位置为3和位置为5的子串匹配。
然后我们按照next数组倒序来做。
对于长度为i的前缀,先判断是否存在长度为i的后缀匹配,如果存在再询问是否存在中间子串。
每次匹配的结果都插入到树状数组里面(因为如果某个位置可以匹配L的前缀,那么实际上1~L-1都能匹配)
然后询问i+1 ~ L-2i+1这个区间里有没有能匹配的子串(即中间的那个串)。
 
  1. #include <iostream>
  2. #include <cstring>
  3. #include <vector>
  4. using namespace std;
  5. const int maxn = 1e6 + ;
  6. char S[maxn];
  7. int Next[maxn], extend[maxn];
  8. vector<int> G[maxn];
  9. int len;
  10. int c[maxn*];
  11. void Modify(int x, int s){
  12. for(; x <= len; x += x&(-x)) c[x] += s;
  13. }
  14. int Query(int y){
  15. if(y <= ) return ;
  16. int ans = ;
  17. for(int x = y; x; x -= x&(-x)) ans += c[x];
  18. return ans;
  19. }
  20. int query(int x, int y) { return x <= y ? Query(y) - Query(x-) : ; }
  21. void GetNext(char *T, int *Next){
  22. int len = strlen(T);
  23. Next[] = len;
  24. int a, p;
  25. for(int i = , j = -; i < len; i++, j--){
  26. if(j < || i + Next[i-a] >= p){
  27. if(j < ) p = i, j = ;
  28. while(p < len && T[p] == T[j])
  29. p++, j++;
  30. Next[i] = j;
  31. a = i;
  32. } else Next[i] = Next[i-a];
  33. }
  34. }
  35. void GetExtend(char *S, char *T, int *extend, int *Next){
  36. GetNext(T, Next);
  37. int a, p;
  38. int slen = strlen(S), tlen = strlen(T);
  39. for(int i = , j = -; i < slen; i++, j--){
  40. if(j < || i + Next[i-a] >= p){
  41. if(j < ) p = i, j = ;
  42. while(p < slen && j < tlen && S[p] == T[j]) p++, j++;
  43. extend[i] = j;
  44. a = i;
  45. } else extend[i] = Next[i-a];
  46. }
  47. }
  48.  
  49. int main()
  50. {
  51. cin>>S;
  52. len = strlen(S);
  53. GetNext(S, Next);
  54. //for(int i = 0; i < len; i++) cout<<Next[i]<<" "; cout<<endl;
  55. for(int i = ; i < len; i++) G[Next[i]].push_back(i);
  56. int ans = ;
  57. for(int i = len-; i >= ; i--){
  58. for(auto x : G[i]) Modify(x+, );
  59. int n = G[i].size();
  60. if(n == ) continue;
  61. if(G[i][n-] != len-i) continue;
  62. if(query(i+, len-*i+)) { ans = i; break; }
  63. }
  64. cout<<ans<<endl;
  65. return ;
  66. }

51nod 1286 三段子串(树状数组+拓展kmp)的更多相关文章

  1. 51Nod 1680 区间求和 树状数组

    题意: 给出一个长度为\(n\)的数列\(A_i\),定义\(f(k)\)为所有长度大于等于\(k\)的子区间中前\(k\)大数之和的和. 求\(\sum_{k=1}^{n}f(k) \; mod \ ...

  2. 51Nod 1272最大距离 (树状数组维护前缀最小值)

    题目链接 最大距离 其实主流解法应该是单调栈……我用了树状数组. #include <bits/stdc++.h> using namespace std; #define rep(i, ...

  3. 51nod 1681 公共祖先 | 树状数组

    51nod 1681 公共祖先 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完 ...

  4. 51nod 1290 Counting Diff Pairs | 莫队 树状数组

    51nod 1290 Counting Diff Pairs | 莫队 树状数组 题面 一个长度为N的正整数数组A,给出一个数K以及Q个查询,每个查询包含2个数l和r,对于每个查询输出从A[i]到A[ ...

  5. ACM学习历程—51NOD 1685 第K大区间2(二分 && 树状数组 && 中位数)

    http://www.51nod.com/contest/problem.html#!problemId=1685 这是这次BSG白山极客挑战赛的E题. 这题可以二分答案t. 关键在于,对于一个t,如 ...

  6. BZOJ 1396:识别子串 SA+树状数组+单调队列

    1396: 识别子串 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 381  Solved: 243[Submit][Status][Discuss] ...

  7. 51nod 1081 子段求和(线段树 | 树状数组 | 前缀和)

    题目链接:子段求和 题意:n个数字序列,m次询问,每次询问从第p个开始L长度序列的子段和为多少. 题解:线段树区间求和 | 树状数组区间求和 线段树: #include <cstdio> ...

  8. 51nod 1680区间求和 (dp+树状数组/线段树)

    不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...

  9. 51nod 麦克打电话(AC自动机+树状数组)

    SAM+线段树合并的裸题. 但我们讨论AC自动机的做法. 先建出AC自动机.考虑询问在[a,b]中出现的次数就是\([1,b]\)的出现次数-\([1,a-1]\)的出现次数.把询问离线.然后我们要求 ...

随机推荐

  1. 北京Uber优步司机奖励政策(12月2日)

    用户组:人民优步(适用于12月2日)奖励政策: 滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:htt ...

  2. [Jmeter]jmeter之BeanShell Sampler测试应用

    前言: 在做接口测试的时候,有些接口做了签名校验,而签名是根据某算法进行加密,这时候,简单的接口测试工具无法完成该工作,所以想到了Jmeter,他是java编写,有强大的扩展性,足矣完成我们需要的操作 ...

  3. Spring Boot中使用缓存

    Spring Boot中使用缓存 随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一. 原始的使 ...

  4. cakephp1.3中help form的一个小问题

    如果我们在模版里这么干 <?php echo $form->input('last_sold_date',array('autocomplete'=>'off','label'=&g ...

  5. python import vs from import

    https://stackoverflow.com/questions/9439480/from-import-vs-import

  6. jmeter获取cookies

    使用场景:登录后,后续的请求操作需获取到JSESSIONID才可进行 1.将jmeter的bin目录下的jmeter.properties文件中的CookieManager.save.cookies= ...

  7. 使用advanced_installer将.net web程序打包为安装程序

    当项目开发完成之后,需要给客户使用时,总不能将发布后的文件全部放一起压缩后直接给客户吧,然后客户需要自行搭建环境修改配置等等,体验太差了,这时候我们就需要使用一种打包工具了,查了一些资料之后,我选择使 ...

  8. 在Unity中使用LitJson解析json文件

    LitJson 这个库需要找资源,找到LitJson.dll后将它放在Assets文件夹下,在脚本中使用using引入即可 测试代码 json文件: {"Archice":[{&q ...

  9. 【setUp-tearDown】线程组开始,结束各执行一次

    使用setUp线程组的方式  ——> 开始 使用tearDown线程组 的方式 ——>结束

  10. Qt窗口及控件-QTreeview/QTableView排序问题

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt-QTreeview/QTableView排序问题     本文地址:http://tec ...