CSU2004:Finding words(含指定不相交前后缀的模式串计数)
题:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2004
题意:给定n个模式串,m个询问,每个询问是“前缀+‘*’+后缀 ”的组合的串S,输出n个模式串中有几个和S是相同的,‘*’可以是0和或更多的字符组成
分析:一般是用给定的模式串来减trie图,但这题显然比较困难,解不出,那么就考虑反过来,我们拿询问的字符串进行构建;
这里要做一下处理:以“后缀+’z+1‘+前缀”地插入trie图,z+1用来代替特殊字符;
因为题目要求的是类似断开的询问串,而我们可以想象一下询问串的首位相连的话,同时将n个模式串首尾链接的话,前缀和后缀就连在一起了且具有唯一性,所以只要我们只要以模式串来跑trie图就行了;
n个模式串的首尾相连根据trie的处理来,就是直接s+’z+1‘+s即可;
至于为啥要用’z+1‘来+在首尾相连的地方,因为如果不加的话,可能这样处理会创造出新的原本不存在的序列出来;
注意,在跑ac自动机的时候要判断长度是否满足条件,因为我们这里相当于把n个模式串扩大了俩倍+1,而查询串的长度不变。
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int M=1e6+;
const int N=1e5+;
const int maxn=;
int ans[N];
struct ac{
int trie[M][maxn],end[M],fail[M],Len[M];
int root,tot;
int newnode(){
for(int i=;i<maxn;i++){
trie[tot][i]=-;
}
end[tot++]=;
return tot-;
}
void init(){
tot=;
root=newnode();
}
void insert(string buf,int id){
int len=buf.size();
int now=root;
for(int i=;i<len;i++){
if(trie[now][buf[i]-'a']==-)
trie[now][buf[i]-'a']=newnode();
now=trie[now][buf[i]-'a'];
}
end[now]=id;
Len[now]=len-;
}
void getfail(){
queue<int>que;
while(!que.empty()){
que.pop();
}
fail[root]=root;
for(int i=;i<maxn;i++){
if(trie[root][i]==-)
trie[root][i]=root;
else{
fail[trie[root][i]]=root;
que.push(trie[root][i]);
}
}
while(!que.empty()){
int now=que.front();
que.pop();
for(int i=;i<maxn;i++){
if(trie[now][i]!=-){
fail[trie[now][i]]=trie[fail[now]][i];
que.push(trie[now][i]);
}
else
trie[now][i]=trie[fail[now]][i];
}
}
}
void query(string buf){
int len=buf.size();
int now=root;
int flag=(len-)/;
for(int i=;i<len;i++){
now=trie[now][buf[i]-'a'];
int tmp=now;
while(tmp!=root){
if(Len[tmp]&&end[tmp]!=&&flag>=Len[tmp])
ans[end[tmp]]++;
tmp=fail[tmp];
}
}
}
}AC;
char sign='z'+;
string s[M];
char buf[];
int main(){ AC.init();
int n;
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%s",buf);
s[i]=buf;
s[i]=s[i]+sign+s[i];
}
int m;
scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%s",buf);
string s2=buf;
if(s2=="*"){
ans[i]=n;
continue;
}
int j;
for(j=;j<s2.size();j++){
if(s2[j]=='*')
break;
}
s2=s2.substr(j+,s2.size()-j-)+sign+s2.substr(,j);
AC.insert(s2,i);
}
AC.getfail();
//cout<<"!!"<<endl;
for(int i=;i<=n;i++){
AC.query(s[i]);
}
for(int i=;i<=m;i++)
printf("%d\n",ans[i]);
return ;
}
CSU2004:Finding words(含指定不相交前后缀的模式串计数)的更多相关文章
- POJ 3376 Finding Palindromes(manacher求前后缀回文串+trie)
题目链接:http://poj.org/problem?id=3376 题目大意:给你n个字符串,这n个字符串可以两两组合形成n*n个字符串,求这些字符串中有几个是回文串. 解题思路:思路参考了这里: ...
- HDU 3613 Best Reward(扩展KMP求前后缀回文串)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分割 ...
- HDU 4763 Theme Section(KMP+枚举公共前后缀)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4763 题目大意: 给你一个字符串s,存在一个子串E同时出现在前缀.中间.后缀,即EAEBE这种模式,A ...
- Hibernate给表和字段设置前后缀及分隔符
在<一口一口吃掉Hibernate(一)--使用SchemaExport生成数据表>中介绍了如何生成数据表.但是这只是最基本的.hibernate在生成或者操作数据库时,会受一些限制.比如 ...
- HDU - 6096 :String (AC自动机,已知前后缀,匹配单词,弱数据)
Bob has a dictionary with N words in it. Now there is a list of words in which the middle part of th ...
- Android删除指定路径下指定前缀或后缀的文件
微信公众号:CodingAndroid CSDN:http://blog.csdn.net/xinpengfei521声明:本文由CodingAndroid原创,未经授权,不可随意转载! 需求 我们在 ...
- 如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀)
原文:如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀) 我们都知道可以通过在 Visual Studio 中设置输出路径(OutputPath)来更改项目输 ...
- Linux下通过脚本自动备份Oracle数据库并删除指定天数前的备份
说明: Oracle数据库服务器操作系统:CentOSIP:192.168.0.198端口:1521SID:orclOracle数据库版本:Oracle11gR2 具体操作: 1.root用户登录服务 ...
- C#实现把指定文件夹下的所有文件复制到指定路径下以及修改指定文件的后缀名
1.实现把指定文件夹下的所有文件复制到指定路径下 public static void copyFiles(string path) { DirectoryInfo dir = new Directo ...
随机推荐
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 图片
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- OpenResty 实现项目的灰度发布
1.安装 openresty 依赖模块: [root@Centos opt]# yum -y install pcre-devel openssl openssl-devel postgresql-d ...
- 编程题目: 两个队列实现栈(Python)
感觉两个队列实现栈 比 两个栈实现队列 麻烦 1.栈为空:当两个队列都为空的时候,栈为空 2.入栈操作:当队列2为空的时候,将元素入队到队列1:当队列1位空的时候,将元素入队到队列2: 如果队列1 和 ...
- JS - 判断字符串某个下标的值
<html><body> <script type="text/javascript"> var str="0123456789!&q ...
- Oralce给字段追加字符,以及oracle 给字段替换字符
追加字符 update table_name t set t.DIST_NAME = t.DIST_NAME || '市' where PROD_NAME='爱立信' table_name :表名 ...
- IDE及PHP基础——注释、变量、数据、运算符、输出等
IDE(Integrated Development Environment ),集成开发环境,是用于提供程序开发环境的应用程序,一般包括代码编辑器.编译器.调试器和图形用户界面等工具.集成了代码编写 ...
- JavaScript基于原型的继承
在一个纯粹的原型模式中,我们会摒弃类,转而专注于对象,基于原型的继承相比基于类的继承的概念上更为简单 if( typeof Object.beget !== 'function') { Object. ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Web基础之Dubbo
Dubbo RPC即Remote Procedure Call,即为远程调用.这和Java的远程代理RMI有点类似,不过RMI只能在Java系统之间进行调用,并且是使用序列化对象的方式进行通信.相比之 ...
- P1042 字符统计
P1042 字符统计 转跳点: