题目链接:hdu_5507_GT and strings

题意:给n个字符串和q个询问,每个询问给两个数字x,y,问1.x是否为y的子序列,2.x是否为y的子串,是输出1,否则输出0,每个询问输出2个数字

题解:

对于子序列,朴素的做法,每次询问的复杂度为max(str[x],str[y]),题目好像有数据卡这个做法,反正会T,正解应该是建立一个序列自动机,首先将所有的字符串连续存起来,用数组来保存每个字符串的位置,然后dp[i][j]表示第i个字符的下一个字符的位置,询问的时候就能做到复杂度为min(str[x],str[y])。、

对于子串,可以用AC自动机来预处理,子串的询问有点特别,不是一般的在树上走,而是对每个节点进行寻找,然后用map来记录关系,不过在询问的时候也有个优化,不加这个优化一样会T,加了瞬间变成170+ms,具体看代码。

  1. #include<bits/stdc++.h>
  2. #define F(i,a,b) for(int i=a;i<=b;i++)
  3. using namespace std;
  4. typedef pair<int,int>P;
  5.  
  6. const int N=1e5+;
  7. int t,n,m,L[N],R[N],loc[N],dp[N][],Q[N][],ans[N][];
  8. char str[N];
  9. map<P,int>ok;
  10. const int AC_N=N,tyn=;//数量乘串长,类型数
  11. struct AC_automation{
  12. int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
  13. inline int getid(char x){return x-'a';}
  14. void nw(){cnt[++tot]=,fail[tot]=;memset(tr[tot],,sizeof(tr[tot]));}
  15. void init(){tot=-,fail[]=-,nw();}
  16. void insert(int l,int r,int x=){
  17. for(int i=l,w;i<=r;x=tr[x][w],loc[i]=x,i++)
  18. if(!tr[x][w=getid(str[i])])nw(),tr[x][w]=tot;
  19. cnt[x]++;//串尾标记
  20. }
  21. void build(int head=,int tail=){
  22. for(int i=;i<tyn;i++)if(tr[][i])Q[++tail]=tr[][i];
  23. while(head<=tail)for(int x=Q[head++],i=;i<tyn;i++)
  24. if(tr[x][i])fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i];
  25. else tr[x][i]=tr[fail[x]][i];
  26. }
  27. void ask(int l,int r)
  28. {
  29. F(i,l,r)for(int p=loc[i];p;p=fail[p])
  30. if(cnt[p])ok[P(p,loc[r])]=;
  31. else if(fail[p]&&!cnt[fail[p]])fail[p]=fail[fail[p]];//决定是否T的优化
  32. }
  33. }AC;
  34.  
  35. void work1()
  36. {
  37. F(i,,)dp[R[n]+][i]=N;//建立“子序列自动机”
  38. for(int i=R[n];i>=;i--)F(j,,)
  39. if(str[i]==j+'a')dp[i][j]=i;
  40. else dp[i][j]=dp[i+][j];
  41. F(i,,m)
  42. {
  43. int x=Q[i][],y=Q[i][];
  44. if(R[x]-L[x]>R[y]-L[y])ans[i][]=;
  45. else
  46. {
  47. ans[i][]=;
  48. for(int j=L[x],p=L[y];j<=R[x];j++,p++)
  49. {
  50. p=dp[p][str[j]-'a'];
  51. if(p>R[y]){ans[i][]=;break;}
  52. }
  53. }
  54. }
  55. }
  56.  
  57. void work2()
  58. {
  59. AC.init(),ok.clear();
  60. F(i,,n)AC.insert(L[i],R[i]);
  61. AC.build();
  62. F(i,,n)AC.ask(L[i],R[i]);
  63. F(i,,m)ans[i][]=ok[P(loc[R[Q[i][]]],loc[R[Q[i][]]])];
  64. }
  65.  
  66. int main()
  67. {
  68. scanf("%d",&t);
  69. while(t--)
  70. {
  71. scanf("%d%d",&n,&m);
  72. int ed=;
  73. F(i,,n)
  74. {
  75. scanf("%s",str+ed);
  76. int len=strlen(str+ed);
  77. L[i]=ed,R[i]=ed+len-,ed=R[i]+;
  78. }
  79. F(i,,m)scanf("%d%d",&Q[i][],&Q[i][]);
  80. work1(),work2();
  81. F(i,,m)printf("%d%d",ans[i][],ans[i][]);
  82. puts("");
  83. }
  84. return ;
  85. }

hdu_5507_GT and strings(AC自动机)的更多相关文章

  1. SPOJ 7758. Growing Strings AC自动机DP

    Growing Strings 题目:给出n个字符串,问最多能够选出多少个串组成序列,并满足前一个字符串是后一个字符串的子串. 分析: AC自动机经典水题... 考虑每个节点结尾时,他能够选出最多的串 ...

  2. hdu 4117 GRE Words AC自动机DP

    题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...

  3. hdu 6208 The Dominator of Strings【AC自动机】

    hdu 6208 The Dominator of Strings[AC自动机] 求一个串包含其他所有串,找出最长串去匹配即可,但是匹配时要对走过的结点标记,不然T死QAQ,,扎心了.. #inclu ...

  4. HDU 6208 The Dominator of Strings(AC自动机)

    The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java ...

  5. HDU 6208 The Dominator of Strings【AC自动机/kmp/Sunday算法】

    Problem Description Here you have a set of strings. A dominator is a string of the set dominating al ...

  6. The Dominator of Strings HDU - 6208(ac自动机板题)

    题意: 就是求是否有一个串 是其它所有串的母串 解析: 把所有的串都加入到trie数中  然后用最长的串去匹配就好了 emm..开始理解错题意了...看成了只要存在一个串是另一个的母串就好.. 然后输 ...

  7. HDU - 6208 The Dominator of Strings HDU - 6208 AC自动机 || 后缀自动机

    https://vjudge.net/problem/HDU-6208 首先可以知道最长那个串肯定是答案 然后,相当于用n - 1个模式串去匹配这个主串,看看有多少个能匹配. 普通kmp的话,每次都要 ...

  8. AC自动机-算法详解

    What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...

  9. 【Codeforces710F】String Set Queries (强制在线)AC自动机 + 二进制分组

    F. String Set Queries time limit per test:3 seconds memory limit per test:768 megabytes input:standa ...

随机推荐

  1. CentOS 6.5安装之后的网络配置

    CentOS 6.5安装之后的网络配置 1.查看IP地址,得到只有一个回环地址 127.0.0.1 2.进行网络测试,现在来测试下,看能不能ping通外网www.baidu.com 下面的是,关于pi ...

  2. Elasticsearch安装ik中文分词插件(四)

    一.IK简介 IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本.最初,它是以开源项目Lu ...

  3. java的三种构造器

    重叠构造器:不可取: javabeans模式:不可取: Builder模式:可取.

  4. CODE[VS]-判断浮点数是否相等-浮点数处理-天梯青铜

    题目描述 Description 给出两个浮点数,请你判断这两个浮点数是否相等 输入描述 Input Description 输入仅一行,包含两个浮点数 输出描述 Output Description ...

  5. U3D音频系统

    一.基本信息 1.支持的声音格式 WAV OGG MP3 AIFF MOD S3M xm IT    导入以后,unity会选择的压缩方式: WAV:无损,音质好,文件大,适用于较短文件 OGG.MP ...

  6. NGINX----源码阅读---config配置脚本

    config文件为nginx的配置入口文件. 1. #!/bin/sh # Copyright (C) Igor Sysoev # Copyright (C) Nginx, Inc. LC_ALL=C ...

  7. CodeForces 711C Coloring Trees

    简单$dp$. $dp[i][j][k]$表示:前$i$个位置染完色,第$i$个位置染的是$j$这种颜色,前$i$个位置分成了$k$组的最小花费.总复杂度$O({n^4})$. #pragma com ...

  8. hdu1032

    #include <iostream> using namespace std; int main() { int a,b,t,i,max; while(cin >> a &g ...

  9. PAT乙级1027. 打印沙漏(20)

    本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数个符号:各行符号中心对齐:相邻两 ...

  10. 《CSS网站布局实录》读书笔记

    从Web标准.HTML标记.CSS语法基础介绍到实用技巧,事无巨细.实体书已不印刷,只能下载电子版 书的背景: 国内第一本web标准的CSS布局书,2006年9月第一版,作者李超. 环境背景: 当时主 ...