题目描述

给你一个串S以及一个字符串数组T[1..m],q次询问,每次问S的子串S[pl​..pr​]在T[l..r]中的哪个串里的出现次数最多,并输出出现次数。

如有多解输出最靠前的那一个。

题解

算是道字符串比较套路的题吧。

对模式串建SAM,对所有模式串的所有前缀维护right集合。

然后对于每个询问,倍增找到关键点,查子树众数。

坑:在最匹配串做匹配的时候,要记录匹配长度,如果匹配长度不够询问长度,直接判无解。

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #define N 1000009
  6. using namespace std;
  7. typedef long long ll;
  8. int ch[N][],tott,tr[N*],id[N*],ls[N*],rs[N*],ans1,ans2,fa[N],mat[N];
  9. int cnt,last,l[N],tot,head[N],n,p[][N],deep[N],T[N],tag[N];
  10. char s[N],s1[N];
  11. inline int rd(){
  12. int x=;char c=getchar();bool f=;
  13. while(!isdigit(c)){if(c=='-')f=;c=getchar();}
  14. while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
  15. return f?-x:x;
  16. }
  17. void upd(int &cnt,int l,int r,int x){
  18. if(!cnt)cnt=++tott;
  19. if(l==r){tr[cnt]++;id[cnt]=l;return;}
  20. int mid=(l+r)>>;
  21. if(mid>=x)upd(ls[cnt],l,mid,x);
  22. else upd(rs[cnt],mid+,r,x);
  23. tr[cnt]=max(tr[ls[cnt]],tr[rs[cnt]]);
  24. id[cnt]=tr[ls[cnt]]>=tr[rs[cnt]]?id[ls[cnt]]:id[rs[cnt]];
  25. }
  26. int merge(int x,int y,int l,int r){
  27. if(!x||!y)return x^y;
  28. int p=++tott;
  29. if(l==r){tr[p]=tr[x]+tr[y];id[p]=l;return p;}
  30. int mid=(l+r)>>;
  31. ls[p]=merge(ls[x],ls[y],l,mid);rs[p]=merge(rs[x],rs[y],mid+,r);
  32. tr[p]=max(tr[ls[p]],tr[rs[p]]);
  33. id[p]=tr[ls[p]]>=tr[rs[p]]?id[ls[p]]:id[rs[p]];
  34. return p;
  35. }
  36. void query(int cnt,int l,int r,int L,int R){
  37. if(!cnt)return;
  38. if(l>=L&&r<=R){
  39. if(tr[cnt]>ans1){
  40. ans1=tr[cnt];
  41. ans2=id[cnt];
  42. }
  43. return;
  44. }
  45. int mid=(l+r)>>;
  46. if(mid>=L)query(ls[cnt],l,mid,L,R);
  47. if(mid<R)query(rs[cnt],mid+,r,L,R);
  48. }
  49. inline void ins(int x,int id){
  50. if(ch[last][x]){
  51. int p=last,q=ch[last][x];
  52. if(l[p]+==l[q])last=q;
  53. else{
  54. int nq=++cnt;l[nq]=l[p]+;
  55. memcpy(ch[nq],ch[q],sizeof(ch[nq]));
  56. fa[nq]=fa[q];fa[q]=nq;
  57. for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
  58. last=nq;
  59. }
  60. }
  61. else{
  62. int p=last,np=++cnt;l[np]=l[p]+;last=np;
  63. for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np;
  64. if(!p)fa[np]=;
  65. else{
  66. int q=ch[p][x];
  67. if(l[p]+==l[q])fa[np]=q;
  68. else{
  69. int nq=++cnt;l[nq]=l[p]+;
  70. memcpy(ch[nq],ch[q],sizeof(ch[nq]));
  71. fa[nq]=fa[q];fa[q]=fa[np]=nq;
  72. for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
  73. }
  74. }
  75. }
  76. upd(T[last],,n,id);
  77. }
  78. struct edge{int n,to;}e[N];
  79. inline void add(int u,int v){e[++tot].n=head[u];e[tot].to=v;head[u]=tot;}
  80. void dfs(int u){
  81. for(int i=;(<<i)<=deep[u];++i)p[i][u]=p[i-][p[i-][u]];
  82. for(int i=head[u];i;i=e[i].n){
  83. int v=e[i].to;deep[v]=deep[u]+;p[][v]=u;
  84. dfs(v);T[u]=merge(T[u],T[v],,n);
  85. }
  86. }
  87. int main(){
  88. scanf("%s",s+);
  89. n=rd();cnt=;
  90. for(int i=;i<=n;++i){
  91. last=;
  92. scanf("%s",s1);int len=strlen(s1);
  93. for(int j=;j<len;++j)ins(s1[j]-'a',i);
  94. }
  95. for(int i=;i<=cnt;++i)if(fa[i])add(fa[i],i);
  96. dfs();int len=strlen(s+),now=,le=;
  97. for(int i=;i<=len;++i){
  98. while(now&&!ch[now][s[i]-'a'])now=fa[now],le=l[now];
  99. if(!now)now=;
  100. if(ch[now][s[i]-'a'])now=ch[now][s[i]-'a'],le++;
  101. tag[i]=now;mat[i]=le;
  102. }
  103. int q=rd(),l1,r1,l2,r2;
  104. while(q--){
  105. l2=rd();r2=rd();l1=rd();r1=rd();
  106. int x=tag[r1];
  107. if(!x||mat[r1]<r1-l1+){
  108. printf("%d 0\n",l2);continue;
  109. }
  110. for(int i=;i>=;--i)if(l[p[i][x]]>=r1-l1+)x=p[i][x];
  111.  
  112. ans1=;ans2=l2;;
  113. query(T[x],,n,l2,r2);
  114. printf("%d %d\n",ans2,ans1);
  115. }
  116. return ;
  117. }

CodeForces666E Forensic Examination的更多相关文章

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

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

  2. Codeforces 666E E - Forensic Examination SA + 莫队 + 线段树

    E - Forensic Examination 我也不知道为什么这个复杂度能过, 而且跑得还挺快, 数据比较水? 在sa上二分出上下界, 然后莫队 + 线段树维护区间众数. #include< ...

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

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

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

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

  5. Codeforces 666E Forensic Examination SAM or SA+线段树合并

    E. Forensic Examination http://codeforces.com/problemset/problem/666/E 题目大意:给模式串S以及m个特殊串,q个询问,询问S的子串 ...

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

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

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

    题目描述 给出 $S$ 串和 $m$ 个 $T_i$ 串,$q$ 次询问,每次询问给出 $l$ .$r$ .$x$ .$y$ ,求 $S_{x...y}$ 在 $T_l,T_{l+1},...,T_r ...

  8. Codeforces 666E Forensic Examination

    题意:给定主串s和m个模式串,每次询问[l,r]的模式串中出现s[pl...pr]次数最多的串和次数. 这题挺简单的,先把所有模式串拿来建广义后缀自动机,询问相当于子树众数,用线段树合并即可. 那我为 ...

  9. [CF 666E] Forensic Examination

    Description 传送门 Solution 对 \(T[1..m]\) 建立广义后缀自动机,离线,找出代表 \(S[pl,pr]\) 的每个节点,线段树合并. Code #include < ...

随机推荐

  1. 两种常用的全排列算法(java)

    问题:给出一个字符串,输出所有可能的排列. 全排列有多种算法,此处仅介绍常用的两种:字典序法和递归法. 1.字典序法: 如何计算字符串的下一个排列了?来考虑"926520"这个字符 ...

  2. Greenplum扩容

    Greenplum支持原有主机扩展Segment个数.新增主机.和混合扩展 本文以在已有机器上扩展节点为例 1.可按照hostname:address:port:fselocation:dbid:co ...

  3. python--继承--方法的重写---和父类的扩展

    1.方法的重写 父类的方法不能满足子类的需要,可以对方法重写 具体的实现方式,就相当于在子类中定义了一个和父类同名的方法并实现 重写之后只会对子类的方法调用,而不会调用父类封装的方法 2.对父类方法进 ...

  4. 在android中进行单元测试的步骤

    若不知道怎么配上面两个参数 

  5. Python基础——2函数

    函数 函数定义 def a(参数): 函数的参数:必选参数.默认参数.可变参数.命名关键字参数和关键字参数 a(x,y,z=11,*l,**b): a(x,y,z=11,*liat,city,job, ...

  6. hbase参数配置优化

    因官方Book Performance Tuning部分章节没有按配置项进行索引,不能达到快速查阅的效果.所以我以配置项驱动,重新整理了原文,并补充一些自己的理解,如有错误,欢迎指正. 配置优化 zo ...

  7. Zookeeper集群为什么要是单数

    (原) 在zookeeper集群中,会有三种角色,leader. follower. observer分别对应着总统.议员.观察者. 半数以上投票通过:可以这样理解.客户端的增删改操作无论访问到了哪台 ...

  8. UVALive - 3523 - Knights of the Round Table

    Problem  UVALive - 3523 - Knights of the Round Table Time Limit: 4500 mSec Problem Description Input ...

  9. token

    18f9nWvThC274lo3USjgfeldynt0t/r/w0yjLbj9 http://app-static.acc5.com/app/testpost.php

  10. 解决 tomcat 重启上传文件消失

    开发模式 首先开发者模式下,部署在 Tomcat 上没有什么好的办法,否则无法调试 除非使用绝对路径,缺点:不同的操作系统路径不同,自动设置 对于图片上传一般我们使用图片服务器,上传 CDN中 一般获 ...