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 ...
随机推荐
- c++ 常见问题之string
string初始化: 拷贝初始化: = 初始化变量,编译器把等号右侧的初始值拷贝到新创建的对象 string s = "stduent"; string s = s1; 直 ...
- sublime 2中Package control安装和使用
安装: 安装时,如果想查看安装进度,可打开console(View->Show Console) 安装Package control有两中方法: 方法1:通过代码安装 import urllib ...
- unity3d打开对话框
最近一直在忙项目,没时间更新博客,这两天趁空封装windows下的打开对话框,支持多选.其他系统可以用ngui或者ugui封装一个. 这里就不上封装的源码了提供dll供小伙伴们使用,如果有需要源码请请 ...
- Unity3DGUI:GUILayout
显示效果,注意GUILayout控件默认垂直布局,且在水平布局模块里控件大小默认按控件内容来显示,因此对于水平滑块HorizontalSlider来说需要自定义大小避免变形
- MyBatis 3 与 Spring 4 整合关键
MyBatis 3 与 Spring 4 整合关键 MyBatis与Spring整合,首先需要一个Spring数据源.其次有两个关键,配置sqlSessionFactory时需要配置扫描sql映射xm ...
- iOS10 CAAnimationDelegate的适配
最近在xcode8打开之前的动画代码,看到如下警告
- [UWP小白日记-1]判断APP是否是第一次运行初始化SQLITE数据库
利用应用程序设置来实现此功能. 1.首先,获取APP设置的容器: ApplicationDataContainer localSettings = ApplicationData.Current.Lo ...
- nodejs 中es5 模块的几种写法
1. module.exports.func = function(){} module.exports.field = ''; 第一种是逐个对api 和字段导出. 2. module.export ...
- 第八章 监控 Zabbix
1.1 YUM部署 Zabbix 2.4 1. 前期准备(省略) l Yum源的配置 cd /etc/yum.repos.d/; mkdir old;mv ./* old/ rpm -Uvh ...
- TypeScript 学习一 参数,函数,析构表达式
1,TypeScript是由谷歌开发的,并且新出的Angular2框架就是谷歌公司由TypeScript语言编写的,所以现在TypeScript是有微软和谷歌一起支持的: 2,TypeScript在j ...