hdu_4787_GRE Words Revenge(在线AC自动机)
题目链接:hdu_4787_GRE Words Revenge
题意:
总共有n个操作,2种操作。每行读入一个字符串。
1.如果字符串以+开头,此为单词(即模式串,不考虑重复)
2.如果字符串以?开头,此为文章(即文本串,查询在此之前的单词在文本串中出现的次数)
题解:
强制在线的AC自动机
贴个大牛的详细题解http://blog.csdn.net/no__stop/article/details/16823479
这样的带合并操作的AC自动机用第二种建树的方式比较方便
#include<bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int AC_N=1e5+,tyn=,M=5e6+;//数量乘串长,类型数
struct AC_automation{
int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
void nw(){cnt[++tot]=;memset(tr[tot],-,sizeof(tr[tot]));}
void init(){tot=-,fail[]=-,nw();}
void insert(char *s,int x=){
for(int i=,w;s[i];x=tr[x][w],i++)
if(tr[x][w=s[i]-'']==-)nw(),tr[x][w]=tot;
cnt[x]=;//串尾标记
}
void build(int head=,int tail=){
F(i,,)if(~tr[][i])Q[++tail]=tr[][i],fail[tr[][i]]=;
while(head<=tail){
for(int i=,x=Q[head++],p=-;i<tyn;i++)if(~tr[x][i]){
for(p=fail[x],fail[tr[x][i]]=;~p;p=fail[p])
if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
Q[++tail]=tr[x][i];
}
}
}
int ask(char *s,int ans=){
for(int w,i=,x=,j;s[i];i++){
while(tr[x][w=s[i]-'']==-&&x)x=fail[x];
x=tr[x][w],x=(~x)?x:,j=x;
while(j){if(cnt[j])ans++;j=fail[j];}
}
return ans;
} }a,b; char s[M],tps[M];
int t,n,an,sqr=,bcnt; void dfs(int r1,int r2)//将b中以r2为根结点的树合并到a中以r1为根结点的树中
{
F(i,,)if(~b.tr[r2][i])
{
if(a.tr[r1][i]==-)a.nw(),a.tr[r1][i]=a.tot;
a.cnt[a.tr[r1][i]]|=b.cnt[b.tr[r2][i]];
dfs(a.tr[r1][i],b.tr[r2][i]);
}
} void join(){dfs(,),b.init(),a.build();}//将b合并到a中 void decrypt()
{
int len=strlen(s);
int k=an%(len-),ed=;
F(i,,len-)tps[i]=s[i];
F(i,k+,len-)s[++ed]=tps[i];
F(i,,k)s[++ed]=tps[i];
} int main()
{
scanf("%d",&t);
F(ic,,t)
{
printf("Case #%d:\n",ic);
scanf("%d",&n);
a.init(),b.init(),an=bcnt=;
F(i,,n)
{
scanf("%s",s),decrypt();
if(s[]=='+')
{
b.insert(s+),b.build(),bcnt++;
if(bcnt>sqr)join();
}else printf("%d\n",(an=a.ask(s+)+b.ask(s+)));
}
}
return ;
}
hdu_4787_GRE Words Revenge(在线AC自动机)的更多相关文章
- HDU4787 GRE Words Revenge【AC自动机 分块】
HDU4787 GRE Words Revenge 题意: \(N\)次操作,每次记录一个\(01\)串或者查询一个\(01\)串能匹配多少个记录的串,强制在线 题解: 在线的AC自动机,利用分块来降 ...
- CodeForces - 710F:String Set Queries (二进制分组 处理 在线AC自动机)
ou should process m queries over a set D of strings. Each query is one of three kinds: Add a string ...
- HDU4787 GRE Words Revenge(AC自动机 分块 合并)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...
- CodeForces 710F 强制在线AC自动机
题目链接:http://codeforces.com/contest/710/problem/F 题意:维护一个集合,集合要求满足三种操作. 1 str:向集合插入字符串str(保证不会插入之前已经插 ...
- 【HDOJ3341】Lost's revenge(AC自动机,DP)
题意:给出一个n个模式串,一个目标串,问把目标串重新排位最多能产生多少个模式串,可以重叠且所有串只包含A C G T. n<=10,len[i]<=10 len(s)<=40 Cas ...
- HDU 3341 Lost's revenge(AC自动机+DP)
Lost's revenge Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- 【HDU3341】 Lost's revenge (AC自动机+状压DP)
Lost's revenge Time Limit: 5000MS Memory Limit: 65535KB 64bit IO Format: %I64d & %I64u Descripti ...
- HDU3341 Lost's revenge(AC自动机+DP)
题目是给一个DNA重新排列使其包含最多的数论基因. 考虑到内存大概就只能这么表示状态: dp[i][A][C][G][T],表示包含各碱基个数为ACGT且当前后缀状态为自动机第i的结点的字符串最多的数 ...
- HDU 3341 Lost's revenge (AC自动机 + DP + 变进制/hash)题解
题意:给你些分数串,给你一个主串,主串每出现一个分数串加一分,要你重新排列主串,最多几分 思路:显然这里开$40^4$去状压内存不够.但是我们自己想想会发现根本不用开那么大,因为很多状态是废状压,不是 ...
随机推荐
- 深入理解Hadoop集群和网络
导读:云计算和Hadoop中网络是讨论得相对比较少的领域.本文原文由Dell企业技术专家Brad Hedlund撰写,他曾在思科工作多年,专长是数据中心.云网络等.文章素材基于作者自己的研究.实验和C ...
- CentOS6.5自带Python2.6.6升级至Python2.7
CentOS6.5中Python2.6升级到Python2.7 由于Python开发团队已不再支持2.6版本,且该版本对一些软件不支持,因此将2.6升级到2.7. 1.安装Python2.7: 下载源 ...
- js导航栏样式变换
<script type="text/javascript"> $(function(){ var lis = $(".submenu").chil ...
- Leetcode easy
1. Two Sum Given an array of integers, return indices of the two numbers such that they add up to a ...
- flume 以 kafka 为channel 的配置
#此配置以kafka的一个topic为channel,相比其他channel类型 file和cache 兼并了快和安全的要求!# Define a kafka channel a1.channels. ...
- java自带的监控工具VisualVM一
转自:http://www.cnblogs.com/wade-xu/p/4369094.html 这篇总结的很不错(本人亲自操手学习),留着以后复习备用,很适合入门级的学习者: VisualVM 是一 ...
- 从键盘或文件中获取标准输入:read命令
文件的描述符和重定向 文件描述符是和文件的输入.输出相关联的非负整数,Linux内核(kernel)利用文件描述符(file descriptor)来访问文件.打开现存文件或新建文件时,内核会返回一个 ...
- 关于eclipse中代码与SVN服务器关联问题
今天开始开发新项目,此项目采用maven搭建,分多个工程,用eclipse的SVN插件检出工程之后只有一个工程,只好用桌面端的SVN工具检出,然后再import导入到eclipse中直接变成了多个工程 ...
- apk反编译查看源码
1.将apk解压
- 通过linux的iso镜像安装(RPM)扩展工具包
通过linux的iso镜像安装(RPM)扩展工具包 在linux安装软件时,现在越来越流行通过rpm指令安装完成,原因是:采用RPM安装简单方便:越来越多的软件提供RPM安装包:linux的IOS镜像 ...