hdu_5507_GT and strings(AC自动机)
题意:给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,具体看代码。
- #include<bits/stdc++.h>
- #define F(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- typedef pair<int,int>P;
- const int N=1e5+;
- int t,n,m,L[N],R[N],loc[N],dp[N][],Q[N][],ans[N][];
- char str[N];
- map<P,int>ok;
- const int AC_N=N,tyn=;//数量乘串长,类型数
- struct AC_automation{
- int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
- inline int getid(char x){return x-'a';}
- void nw(){cnt[++tot]=,fail[tot]=;memset(tr[tot],,sizeof(tr[tot]));}
- void init(){tot=-,fail[]=-,nw();}
- void insert(int l,int r,int x=){
- for(int i=l,w;i<=r;x=tr[x][w],loc[i]=x,i++)
- if(!tr[x][w=getid(str[i])])nw(),tr[x][w]=tot;
- cnt[x]++;//串尾标记
- }
- void build(int head=,int tail=){
- for(int i=;i<tyn;i++)if(tr[][i])Q[++tail]=tr[][i];
- while(head<=tail)for(int x=Q[head++],i=;i<tyn;i++)
- if(tr[x][i])fail[tr[x][i]]=tr[fail[x]][i],Q[++tail]=tr[x][i];
- else tr[x][i]=tr[fail[x]][i];
- }
- void ask(int l,int r)
- {
- F(i,l,r)for(int p=loc[i];p;p=fail[p])
- if(cnt[p])ok[P(p,loc[r])]=;
- else if(fail[p]&&!cnt[fail[p]])fail[p]=fail[fail[p]];//决定是否T的优化
- }
- }AC;
- void work1()
- {
- F(i,,)dp[R[n]+][i]=N;//建立“子序列自动机”
- for(int i=R[n];i>=;i--)F(j,,)
- if(str[i]==j+'a')dp[i][j]=i;
- else dp[i][j]=dp[i+][j];
- F(i,,m)
- {
- int x=Q[i][],y=Q[i][];
- if(R[x]-L[x]>R[y]-L[y])ans[i][]=;
- else
- {
- ans[i][]=;
- for(int j=L[x],p=L[y];j<=R[x];j++,p++)
- {
- p=dp[p][str[j]-'a'];
- if(p>R[y]){ans[i][]=;break;}
- }
- }
- }
- }
- void work2()
- {
- AC.init(),ok.clear();
- F(i,,n)AC.insert(L[i],R[i]);
- AC.build();
- F(i,,n)AC.ask(L[i],R[i]);
- F(i,,m)ans[i][]=ok[P(loc[R[Q[i][]]],loc[R[Q[i][]]])];
- }
- int main()
- {
- scanf("%d",&t);
- while(t--)
- {
- scanf("%d%d",&n,&m);
- int ed=;
- F(i,,n)
- {
- scanf("%s",str+ed);
- int len=strlen(str+ed);
- L[i]=ed,R[i]=ed+len-,ed=R[i]+;
- }
- F(i,,m)scanf("%d%d",&Q[i][],&Q[i][]);
- work1(),work2();
- F(i,,m)printf("%d%d",ans[i][],ans[i][]);
- puts("");
- }
- return ;
- }
hdu_5507_GT and strings(AC自动机)的更多相关文章
- SPOJ 7758. Growing Strings AC自动机DP
Growing Strings 题目:给出n个字符串,问最多能够选出多少个串组成序列,并满足前一个字符串是后一个字符串的子串. 分析: AC自动机经典水题... 考虑每个节点结尾时,他能够选出最多的串 ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 6208 The Dominator of Strings【AC自动机】
hdu 6208 The Dominator of Strings[AC自动机] 求一个串包含其他所有串,找出最长串去匹配即可,但是匹配时要对走过的结点标记,不然T死QAQ,,扎心了.. #inclu ...
- HDU 6208 The Dominator of Strings(AC自动机)
The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java ...
- 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 ...
- The Dominator of Strings HDU - 6208(ac自动机板题)
题意: 就是求是否有一个串 是其它所有串的母串 解析: 把所有的串都加入到trie数中 然后用最长的串去匹配就好了 emm..开始理解错题意了...看成了只要存在一个串是另一个的母串就好.. 然后输 ...
- HDU - 6208 The Dominator of Strings HDU - 6208 AC自动机 || 后缀自动机
https://vjudge.net/problem/HDU-6208 首先可以知道最长那个串肯定是答案 然后,相当于用n - 1个模式串去匹配这个主串,看看有多少个能匹配. 普通kmp的话,每次都要 ...
- AC自动机-算法详解
What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...
- 【Codeforces710F】String Set Queries (强制在线)AC自动机 + 二进制分组
F. String Set Queries time limit per test:3 seconds memory limit per test:768 megabytes input:standa ...
随机推荐
- CentOS 6.5安装之后的网络配置
CentOS 6.5安装之后的网络配置 1.查看IP地址,得到只有一个回环地址 127.0.0.1 2.进行网络测试,现在来测试下,看能不能ping通外网www.baidu.com 下面的是,关于pi ...
- Elasticsearch安装ik中文分词插件(四)
一.IK简介 IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本.最初,它是以开源项目Lu ...
- java的三种构造器
重叠构造器:不可取: javabeans模式:不可取: Builder模式:可取.
- CODE[VS]-判断浮点数是否相等-浮点数处理-天梯青铜
题目描述 Description 给出两个浮点数,请你判断这两个浮点数是否相等 输入描述 Input Description 输入仅一行,包含两个浮点数 输出描述 Output Description ...
- U3D音频系统
一.基本信息 1.支持的声音格式 WAV OGG MP3 AIFF MOD S3M xm IT 导入以后,unity会选择的压缩方式: WAV:无损,音质好,文件大,适用于较短文件 OGG.MP ...
- NGINX----源码阅读---config配置脚本
config文件为nginx的配置入口文件. 1. #!/bin/sh # Copyright (C) Igor Sysoev # Copyright (C) Nginx, Inc. LC_ALL=C ...
- CodeForces 711C Coloring Trees
简单$dp$. $dp[i][j][k]$表示:前$i$个位置染完色,第$i$个位置染的是$j$这种颜色,前$i$个位置分成了$k$组的最小花费.总复杂度$O({n^4})$. #pragma com ...
- hdu1032
#include <iostream> using namespace std; int main() { int a,b,t,i,max; while(cin >> a &g ...
- PAT乙级1027. 打印沙漏(20)
本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数个符号:各行符号中心对齐:相邻两 ...
- 《CSS网站布局实录》读书笔记
从Web标准.HTML标记.CSS语法基础介绍到实用技巧,事无巨细.实体书已不印刷,只能下载电子版 书的背景: 国内第一本web标准的CSS布局书,2006年9月第一版,作者李超. 环境背景: 当时主 ...