【CF316G3】Good Substrings

题意:给出n个限制(p,l,r),我们称一个字符串满足一个限制当且仅当这个字符串在p中的出现次数在[l,r]之间。现在想问你S的所有本质不同的子串中,有多少个满足所有限制。

|S|,|p|<=10^5,n<=10。

题解:比较简单的后缀自动机题,我们先把原串和所有限制串放到一起建一个广义后缀自动机,然后在pre树上统计一下即可得到每个子串在每个限制串中出现了多少次。现在我们想知道原串中有多少满足条件的子串,即我们统计一下所有出现次数符合要求的,且在原串中出现过的点的贡献即可。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. using namespace std;
  6. const int N=1100010;
  7. int n,cnt,tot,last,ans;
  8. int len[11],L[11],R[11],s[N][11],ch[N][26],pre[N],mx[N],to[N],nxt[N],head[N],ml[N];
  9. char S[11][50010];
  10. inline void extend(int x)
  11. {
  12. int p=last;
  13. if(ch[p][x])
  14. {
  15. int q=ch[p][x];
  16. if(mx[q]==mx[p]+1) last=q;
  17. else
  18. {
  19. int nq=++tot;
  20. pre[nq]=pre[q],pre[q]=nq,mx[nq]=mx[p]+1,last=nq;
  21. memcpy(ch[nq],ch[q],sizeof(ch[q]));
  22. for(;p&&ch[p][x]==q;p=pre[p]) ch[p][x]=nq;
  23. }
  24. }
  25. else
  26. {
  27. int np=++tot;
  28. last=np,mx[np]=mx[p]+1;
  29. for(;p&&!ch[p][x];p=pre[p]) ch[p][x]=np;
  30. if(!p) pre[np]=1;
  31. else
  32. {
  33. int q=ch[p][x];
  34. if(mx[q]==mx[p]+1) pre[np]=q;
  35. else
  36. {
  37. int nq=++tot;
  38. pre[nq]=pre[q],pre[q]=pre[np]=nq,mx[nq]=mx[p]+1;
  39. memcpy(ch[nq],ch[q],sizeof(ch[q]));
  40. for(;p&&ch[p][x]==q;p=pre[p]) ch[p][x]=nq;
  41. }
  42. }
  43. }
  44. }
  45. inline void add(int a,int b)
  46. {
  47. to[cnt]=b,nxt[cnt]=head[a],head[a]=cnt++;
  48. }
  49. void dfs(int x)
  50. {
  51. for(int i=head[x],j;i!=-1;i=nxt[i])
  52. {
  53. dfs(to[i]);
  54. for(j=0;j<=n;j++) s[x][j]+=s[to[i]][j];
  55. }
  56. }
  57. int main()
  58. {
  59. scanf("%s%d",S[0],&n),len[0]=strlen(S[0]);
  60. int i,j;
  61. last=tot=1;
  62. memset(head,-1,sizeof(head));
  63. for(i=1;i<=n;i++) scanf("%s%d%d",S[i],&L[i],&R[i]),len[i]=strlen(S[i]);
  64. for(i=0;i<=n;i++)
  65. for(last=1,j=0;j<len[i];j++)
  66. extend(S[i][j]-'a'),s[last][i]++;
  67. for(i=2;i<=tot;i++) add(pre[i],i);
  68. dfs(1);
  69. for(i=2;i<=tot;i++) if(s[i][0])
  70. {
  71. for(j=1;j<=n;j++) if(s[i][j]<L[j]||s[i][j]>R[j]) break;
  72. if(j>n) ans+=(mx[i]-mx[pre[i]]);
  73. }
  74. printf("%d",ans);
  75. return 0;
  76. }

【CF316G3】Good Substrings 后缀自动机的更多相关文章

  1. SPOJ NSUBSTR Substrings 后缀自动机

    人生第一道后缀自动机,总是值得纪念的嘛.. 后缀自动机学了很久很久,先是看CJL的论文,看懂了很多概念,关于right集,关于pre,关于自动机的术语,关于为什么它是线性的结点,线性的连边.许多铺垫的 ...

  2. ●SPOJ 8222 NSUBSTR–Substrings(后缀自动机)

    题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 后缀自动机的水好深啊!懂不了相关证明,带着结论把这个题做了.看来这滩深水要以后再来了. 本题要用到一个叫 R ...

  3. SPOJ8222 NSUBSTR - Substrings(后缀自动机)

    You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as ...

  4. SPOJ NSUBSTR Substrings ——后缀自动机

    建后缀自动机 然后统计次数,只需要算出right集合的大小即可, 然后更新f[l[i]]和rit[i]取个max 然后根据rit集合短的一定包含长的的性质,从后往前更新一遍即可 #include &l ...

  5. spoj 8222 Substrings (后缀自动机)

    spoj 8222 Substrings 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) 解题思路:我们构造S的SAM,那么对于 ...

  6. UVA - 10829 L-Gap Substrings (后缀自动机+线段树启发式合并)

    题意:统计一段字符串中形如UVU的子串个数(其中V的长度固定为g). 问题等价于求满足$g+1\leqslant |j-i|\leqslant g+LCP(i,j)$的后缀(i,j)的对数,即$\su ...

  7. SPOJ8222 Substrings( 后缀自动机 + dp )

    题目大意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.F(1)..F(Length(S)) 建出SAM, 然后求出Right, 求Right可以按拓扑序dp..Right ...

  8. SPOJ8222 NSUBSTR - Substrings 后缀自动机_动态规划

    讲起来不是特别好讲.总之,如果 $dp[i+1]>=dp[i]$,故$dp[i]=max(dp[i],dp[i+1])$ Code: #include <cstdio> #inclu ...

  9. SP8222 NSUBSTR - Substrings(后缀自动机+dp)

    传送门 解题思路 首先建出\(sam\),然后把\(siz\)集合通过拓扑排序算出来.对于每个点只更新它的\(maxlen\),然后再从大到小\(dp\)一次就行了.因为\(f[maxlen-1]&g ...

随机推荐

  1. EasyUI的功能树之异步树

    最近几个项目都用到了EasyUI这个Jquery框架,目前感觉起来还是很好使的,展示效果很好,帮助文档什么的资料很多,而且互联网上Easy粉很多,大多数拥护和喜爱EasyUI的粉丝们都愿意在网络平台互 ...

  2. Objective-C语法之NSPredicate的使用

    正则表达式判断手机号码和电话号码的方法: #import <Foundation/Foundation.h> /** 正则判断手机号码地址格式 */ BOOL isMobileNumber ...

  3. kafka学习之-KafkaOffsetMonitor后台监控

    1.下载Kafka Consumer Offset Monitor安装包 http://pan.baidu.com/s/1ntzIUPN 2.在/usr/local/hadoop路径下面建立放置Kaf ...

  4. 理解Node.js异步非阻塞I/O与传统线性阻塞IO的区别(转)

    阻塞I/O 程序执行过程中必然要进行很多I/O操作,读写文件.输入输出.请求响应等等.I/O操作时最费时的,至少相对于代码来说,在传统的编程模式中,举个例子,你要读一个文件,整个线程都暂停下来,等待文 ...

  5. 找不到 android-support-v4 解决办法

    Project->properties->Java Build Path->Libraries->Add External Jars中加入sdk目录下的extras/andro ...

  6. android project 文件夹

    android多国语言文件夹 http://www.blogjava.net/zhaojianhua/archive/2012/02/09/369676.html Android平板开发精确适配不同的 ...

  7. 求字符串长度StringLength();

    // StringLength2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" int StringLength(char str[]) ...

  8. [转] 关于QT的系统总结

    出处:http://www.cnblogs.com/wangqiguo/p/4625611.html 阅读目录 编译环境与开发流程 QT项目的构成及原理 QT中的布局 QT中的通用控件 QVarian ...

  9. Linux下的ssh远程访问

    准备工作:首先需要在windows系统中安装虚拟机,并在虚拟机中安装好linux操作系统,这里安装的是vmware player虚拟机和ubuntu版本的操作系统.关于该部分的安装在作者的其他经验中有 ...

  10. 2、一、Introduction(入门):1、Application Fundamentals(应用程序基础)

    一.Introduction(入门) 1.Application Fundamentals(应用程序基础) Android apps are written in the Java programmi ...