题目

每天一道\(SAM\)真是非常开心

一看就是广义\(SAM\)+线段树合并了

我们存好\(S\)串每一个前缀的终点,之后在\(parent\)树上倍增找到表示\(S[l,r]\)这个子串的节点,我们用线段树合并维护好\(endpos\)集合,查一个区间最大值就好了

代码

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #define maxn 2000005
  6. #define M 10000005
  7. #define re register
  8. #define LL long long
  9. #define mp std::make_pair
  10. #define max(a,b) ((a)>(b)?(a):(b))
  11. #define min(a,b) ((a)<(b)?(a):(b))
  12. typedef std::pair<int,int> pii;
  13. struct E{int v,nxt;}e[maxn];
  14. char S[maxn];
  15. int len[maxn],fa[maxn],son[maxn][26],endpos[maxn],to[maxn],head[maxn],rt[maxn];
  16. int f[maxn][22],deep[maxn],loog[maxn];
  17. int n,m,Q,__,num,lst=1,cnt=1,tot;
  18. int l[M],r[M],sum[M],d[M];
  19. inline void add(int x,int y){e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
  20. inline void pushup(int x) {
  21. if(sum[l[x]]>=sum[r[x]]) sum[x]=sum[l[x]],d[x]=d[l[x]];
  22. else sum[x]=sum[r[x]],d[x]=d[r[x]];
  23. }
  24. int change(int now,int x,int y,int pos) {
  25. if(!now) now=++tot;
  26. if(x==y) {sum[now]++;d[now]=x;return now;}
  27. int mid=x+y>>1;
  28. if(pos<=mid) l[now]=change(l[now],x,mid,pos);
  29. else r[now]=change(r[now],mid+1,y,pos);
  30. pushup(now);
  31. return now;
  32. }
  33. int merge(int a,int b,int x,int y) {
  34. if(!a) return b;if(!b) return a;
  35. int root=++tot;
  36. if(x==y) {sum[root]=sum[a]+sum[b],d[root]=x;return root;}
  37. int mid=x+y>>1;
  38. l[root]=merge(l[a],l[b],x,mid),r[root]=merge(r[a],r[b],mid+1,y);
  39. pushup(root);
  40. return root;
  41. }
  42. inline void ins(int c,int o) {
  43. int p=++cnt,f=lst; lst=p;
  44. len[p]=len[f]+1;
  45. if(!o) to[++__]=p;
  46. else rt[p]=change(rt[p],1,m,o);
  47. while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
  48. if(!f) {fa[p]=1;return;}
  49. int x=son[f][c];
  50. if(len[f]+1==len[x]) {fa[p]=x;return;}
  51. int y=++cnt;
  52. len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
  53. for(re int i=0;i<26;i++) son[y][i]=son[x][i];
  54. while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
  55. }
  56. void dfs(int x) {
  57. for(re int i=head[x];i;i=e[i].nxt)
  58. deep[e[i].v]=deep[x]+1,dfs(e[i].v),rt[x]=merge(rt[x],rt[e[i].v],1,m);
  59. }
  60. pii query(int now,int x,int y,int lx,int ry)
  61. {
  62. if(lx<=x&&ry>=y) return mp(sum[now],d[now]);
  63. int mid=x+y>>1;
  64. if(ry<=mid) return query(l[now],x,mid,lx,ry);
  65. if(lx>mid) return query(r[now],mid+1,y,lx,ry);
  66. pii a=query(l[now],x,mid,lx,ry),b=query(r[now],mid+1,y,lx,ry);
  67. if(a.first>=b.first) return a; return b;
  68. }
  69. int main()
  70. {
  71. scanf("%s",S+1);n=strlen(S+1);
  72. for(re int i=1;i<=n;i++) ins(S[i]-'a',0);
  73. scanf("%d",&m);
  74. for(re int i=1;i<=m;i++)
  75. {
  76. scanf("%s",S+1);n=strlen(S+1);lst=1;
  77. for(re int j=1;j<=n;j++) ins(S[j]-'a',i);
  78. }
  79. for(re int i=2;i<=cnt;i++) add(fa[i],i);
  80. deep[1]=1,dfs(1);
  81. for(re int i=1;i<=cnt;i++) f[i][0]=fa[i];
  82. for(re int i=2;i<=cnt;i++) loog[i]=loog[i>>1]+1;
  83. for(re int j=1;j<=loog[cnt];j++)
  84. for(re int i=1;i<=cnt;i++)
  85. f[i][j]=f[f[i][j-1]][j-1];
  86. scanf("%d",&Q);
  87. int x,y,L,R;
  88. while(Q--)
  89. {
  90. scanf("%d%d%d%d",&x,&y,&L,&R);
  91. int Len=R-L+1;
  92. int now=to[R];
  93. for(re int i=loog[deep[now]];i>=0;--i)
  94. if(f[now][i]&&len[f[now][i]]>=Len) now=f[now][i];
  95. pii ans=query(rt[now],1,m,x,y);
  96. if(ans.first) printf("%d %d\n",ans.second,ans.first);
  97. else printf("%d ",x),puts("0");
  98. }
  99. return 0;
  100. }

CF666E 【Forensic Examination】的更多相关文章

  1. 【CF666E】Forensic Examination 广义后缀自动机+倍增+线段树合并

    [CF666E]Forensic Examination 题意:给你一个字符串s和一个字符串集合$\{t_i\}$.有q个询问,每次给出$l,r,p_l,p_r$,问$s[p_l,p_r]$在$t_l ...

  2. 【CF666E】Forensic Examination(后缀自动机,线段树合并)

    [CF666E]Forensic Examination(后缀自动机,线段树合并) 题面 洛谷 CF 翻译: 给定一个串\(S\)和若干个串\(T_i\) 每次询问\(S[pl..pr]\)在\(T_ ...

  3. 【Codeforces666E】Forensic Examination 后缀自动机 + 线段树合并

    E. Forensic Examination time limit per test:6 seconds memory limit per test:768 megabytes input:stan ...

  4. CF 666E Forensic Examination 【SAM 倍增 线段树合并】

    CF 666E Forensic Examination 题意: 给出一个串\(s\)和\(n\)个串\(t_i\),\(q\)次询问,每次询问串\(s\)的子串\(s[p_l:p_r]\)在串\(t ...

  5. 【AR实验室】mulberryAR : ORBSLAM2+VVSION

    本文转载请注明出处 —— polobymulberry-博客园 0x00 - 前言 mulberryAR是我业余时间弄的一个AR引擎,目前主要支持单目视觉SLAM+3D渲染,并且支持iOS端,但是该引 ...

  6. 【.net 深呼吸】细说CodeDom(1):结构大观

    CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...

  7. 【Machine Learning】KNN算法虹膜图片识别

    K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  8. 【前端性能】高性能滚动 scroll 及页面渲染优化

    最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...

  9. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

随机推荐

  1. linux运维基础之系统挂载与etc文件下介绍

    1) 目录结构说明: windows:磁盘----分区---格式化--系统 linux:磁盘--分区--生成一个文件(磁盘分区) linux 中一切皆文件 ll -h 显示人类能看懂的 mount - ...

  2. ubuntu安装VMware Tools报错enter the path to the kernel header files

    $ sudo apt-get install build-essential linux-headers-$(uname -r) cd /lib/modules/$(uname -r)/build/i ...

  3. [linux] uptime 命令中关于平均负载的解释

    1.当前时间 00:13:25 2.系统已运行的时间 9小时19分 3.当前在线用户 2 user 4.平均负载:0.17, 0.12, 0.07 最近1分钟.5分钟.15分钟系统的负载 为了更好地理 ...

  4. shell中if的可判断的类型

    -d :判断制定的是否为目录-z:判断制定的变量是否存在值-f:判断制定的是否为文件-L:判断制定的是否为符号链接-r:判断制定的是否可读-w:判断制定的是否可写-x:判断存在的对象是否可以执行!:测 ...

  5. 机器学习——XGBoost

    基础概念 XGBoost(eXtreme Gradient Boosting)是GradientBoosting算法的一个优化的版本,针对传统GBDT算法做了很多细节改进,包括损失函数.正则化.切分点 ...

  6. 如何运营亿级QPS的Redis系统

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 作者:冯伟源,高级工程师,腾讯云Redis系统运维负责人.6年DBA经验,一直从事SQL优化.实例调优.数据库架构.海量数据库集群运维.运营 ...

  7. 【Shell】shell截取字符串方式(cut、awk、sed命令)

    1.cut -b :以字节为单位进行分割.这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志.-c :以字符为单位进行分割. -d:自定义分隔符,默认为制表符. -f:与-d一起使用,指定显示 ...

  8. js跑步算法

    <!DOCTYPE html> <html> <head> <title>JavaScript</title> <style> ...

  9. Introduction of Servlet Filter(了解Servlet之Filter)

    API文档中介绍了public Interface Filter(公共接口过滤器) Servlet API文档中是这样介绍的: ‘A filter is an object that performs ...

  10. C#学习笔记4

    1.C#只支持单一继承,若想要实现多重继承的效果.有2种方式: 第一种为传递继承,A为基类,B继承A,C继承B,通过传递来增迭要包含的元素,但这种继承的设计,在业务上具有明显的从属关系. 第二种为聚合 ...