题解:

  枚举x位置,向左右延伸计算答案

  如何计算答案:对字符串建立SA,那么对于想双延伸的长度L,假如有lcp(i-L,i+1)>=L那么就可以更新答案

  复杂度  建立SA,LCP等nlogn,枚举X及向两边延伸26*n

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cmath>
  6. using namespace std;
  7. #pragma comment(linker, "/STACK:102400000,102400000")
  8. #define ls i<<1
  9. #define rs ls | 1
  10. #define mid ((ll+rr)>>1)
  11. #define pii pair<int,int>
  12. #define MP make_pair
  13. typedef long long LL;
  14. const long long INF = 1e18+1LL;
  15. const double Pi = acos(-1.0);
  16. const int N = 1e5+, M = 2e5+, mod = 1e9+, inf = 2e9;
  17.  
  18. ///heght[i] 表示 Suffix(sa[i-1])和Suffix(sa[i]) 的最长公共前缀:
  19. ///rank[i] 表示 开头为i的后缀的等级:
  20. ///sa[i] 表示 排名为i的后缀 的开头位置:
  21. int *rank,r[N],sa[N],height[N],wa[N],wb[N],wm[N];
  22. bool cmp(int *r,int a,int b,int l) {
  23. return r[a] == r[b] && r[a+l] == r[b+l];
  24. }
  25. void SA(int *r,int *sa,int n,int m) {
  26. int *x=wa,*y=wb,*t;
  27. for(int i=;i<m;++i)wm[i]=;
  28. for(int i=;i<n;++i)wm[x[i]=r[i]]++;
  29. for(int i=;i<m;++i)wm[i]+=wm[i-];
  30. for(int i=n-;i>=;--i)sa[--wm[x[i]]]=i;
  31. for(int i=,j=,p=;p<n;j=j*,m=p){
  32. for(p=,i=n-j;i<n;++i)y[p++]=i;
  33. for(i=;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;
  34. for(i=;i<m;++i)wm[i]=;
  35. for(i=;i<n;++i)wm[x[y[i]]]++;
  36. for(i=;i<m;++i)wm[i]+=wm[i-];
  37. for(i=n-;i>=;--i)sa[--wm[x[y[i]]]]=y[i];
  38. for(t=x,x=y,y=t,i=p=,x[sa[]]=;i<n;++i) {
  39. x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
  40. }
  41. }
  42. rank=x;
  43. }
  44. void Height(int *r,int *sa,int n) {
  45. for(int i=,j=,k=;i<n;height[rank[i++]]=k)
  46. for(k?--k:,j=sa[rank[i]-];r[i+k] == r[j+k];++k);
  47. }
  48.  
  49. int dp[N][],n;
  50. char a[N];
  51. void Lcp_init() {
  52. for(int i = ; i <= n; ++i) dp[i][] = height[i];
  53. for(int j = ; (<<j) <= n; ++j) {
  54. for(int i = ; i + (<<j) - <= n; ++i) {
  55. dp[i][j] = min(dp[i][j-],dp[i+(<<(j-))][j-]);
  56. }
  57. }
  58. }
  59. int lcp(int l,int r) {
  60. if(l > r) swap(l,r);
  61. l++;
  62. int len = r - l + ;
  63. int k = ;
  64. while((<<(k+)) <= len) k++;
  65. return min(dp[l][k],dp[r - (<<k) + ][k]);
  66. }
  67. int main() {
  68. int T;
  69. scanf("%d",&T);
  70. while(T--) {
  71. scanf("%s",a);
  72. n = strlen(a);
  73. for(int i = ; i < n; ++i) r[i] = a[i] - 'a' + ;
  74. r[n] = ;
  75. SA(r,sa,n+,);
  76. Height(r,sa,n);
  77. Lcp_init();
  78. LL ans = ;
  79. for(int i = ; i < n-; ++i) {
  80. int L = ;
  81. while(i - L >= && i + L < n) {
  82. if(a[i] == a[i-L] || a[i] == a[i + L]) break;
  83. if(lcp(rank[i-L],rank[i+]) >= L) ans += 1LL * (*L+) * (*L+);
  84. L++;
  85. }
  86. }
  87. printf("%I64d\n",ans);
  88. }
  89. return ;
  90. }

FZU 2137 奇异字符串 后缀树组+RMQ的更多相关文章

  1. 【BZOJ-1396&2865】识别子串&字符串识别 后缀自动机/后缀树组 + 线段树

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

  2. 【BZOJ3277/3473】串/字符串 后缀数组+二分+RMQ+双指针

    [BZOJ3277]串 Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Inpu ...

  3. CF504E Misha and LCP on Tree(树链剖分+后缀树组)

    1A真舒服. 喜闻乐见的树链剖分+SA. 一个初步的想法就是用树链剖分,把两个字符串求出然后hash+二分求lcp...不存在的. 因为考虑到这个字符串是有序的,我们需要把每一条重链对应的字符串和这个 ...

  4. HDU4436---str2int 后缀树组(12年天津区域赛)

    str2int Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

  5. SPOJ694 -- DISUBSTR 后缀树组求不相同的子串的个数

    DISUBSTR - Distinct Substrings   Given a string, we need to find the total number of its distinct su ...

  6. POJ3581---Sequence 后缀树组

    题意:n个数字组成的序列,第一个数字最大,,把序列分成3部分,每个部分分别翻转,输出翻转后字典序最小的序列.. 后缀数组变一下,,先求出 第一个分割的位置,,然后再求一次后缀数组,,求出第二个位置.. ...

  7. 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组

    涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...

  8. 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树

    另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...

  9. 洛谷P5284 [十二省联考2019]字符串问题 [后缀树]

    传送门 思路 设\(dp_i\)表示以\(i\)结尾的\(A\)串,能达到的最长长度. 然后发现这显然可以\(i\)往自己控制的\(k\)连边,\(k\)往能匹配的\(j\)连边,就是个最长路,只要建 ...

随机推荐

  1. Backbone事件模块及其用法

    事件模块Backbone.Events在Backbone中占有十分重要的位置,其他模块Model,Collection,View所有事件模块都依赖它.通过继承Events的方法来实现事件的管理,可以说 ...

  2. iOS多线程-RunLoop简介

    什么是RunLoop? 从字面上来看是运行循环的意思. 内部就是一个do{}while循环,在这个循环里内部不断的处理各种任务(比如:source/timer/Observer) RunLoop的存在 ...

  3. C语言: 运算符,printf,scanf的用法

    运算符/的运算结果和运算对象的数据类型有关,两个数都是in,则商就是int,取整数部分:被除数和除数中只要有一个或两个都是浮点型数据,则商也是浮点型,不去掉小数部分如:16/5 == 3:16/5.0 ...

  4. 群集中的MS DTC分布式事务协调器

    MS DTC在大多数SQL 服务器下都需要安装,若只是安装数据库引擎或Analysis 服务可不安装DTC.如果后需要使用分布式事务,则可在SQL Server群集安装完成后再安装DTC. 一.群集M ...

  5. Eclipse 导入外部项目无法识别为web项目并且无法在部署到tomcat下

    uss_web如果没有左上角那个球,tomcat就识别不出来的. 1.进入项目目录,找到.project文件,打开. 2.找到...代码段,加入如下标签内容并保存: <nature>org ...

  6. adb install INSTALL_FAILED_ALREADY_EXISTS

    安装时候碰到的一个问题:已经签名的包,重新通过adb install 会提示安装错误.提示:Failure [INSTALL_FAILED_ALREADY_EXISTS] 为啥eclipse自己就可以 ...

  7. Hibernate简易原生DAO的实现

    写在最前: 初学Hibernate,在尝试把JDBC项目移植到Hibernate的过程中,碰到了不少的麻烦,最让人心烦意乱的自然是SQL语句改动造成的代码混乱.其实不难,网上的解决方案有很多, 不过. ...

  8. tips~function pointer

    An simple example: #include<stdio.h> int plus(int a,int b) { return a+b; } int main() { int (* ...

  9. yum 操作复习

    RPM与YUM是配合使用的. rpm负责从网站或指定的文件路径,获取到rpm软件包.也就是说你要安装什么服务或软件,就要先找到rpm包,下载下来.也就是通常说的配置yum源. 啥是yum源.你下载下的 ...

  10. Postgresql 简单配置 (ubuntu server 14.04.3)

    安装和配置 ubuntu server 已经自动安装了progresql,故安装步骤就省略 初始postgresql没有密码,不能使用,需要先设置密码,命令(从网上随意找的)如下: sudo su p ...