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 ...
随机推荐
- layerui上传文件
参考: http://www.layui.com/doc/modules/upload.html <1> 文件上传(以下函数必须要在js文件加载时执行) upload.render({ e ...
- Elasticsearch的快速使用——Spring Boot使用Elastcisearch, 并且使用Logstash同步mysql和Elasticsearch的数据
我主要是给出一些方向,很多地方没有详细说明.当时我学习的时候一直不知道怎么着手,花时间找入口点上比较多,你们可以直接顺着方向去找资源学习. 如果不是Spring Boot项目,那么根据Elastics ...
- '/'和‘/*’差异造成的No mapping found for HTTP request with URI [/springMVC/welcome.jsp] in DispatcherServlet with name 'springmvc'
在采用springMVC框架的时候所遇到的一个小问题,其中web.xml中关于servlet的配置如下: <servlet> <servlet-name>springmvc&l ...
- [Codeforces #608 div2]1272B Blocks
Description There are nnn blocks arranged in a row and numbered from left to right, starting from on ...
- 单选与多选与label
单选radio和多选checkbox是用name属性关联的 相同的name就相当于同一道题 <input type="radio" name="radio" ...
- mysql实现ORACLE的connect by prior父子递归查询
oracle中有connect by prior ,可以实现父子递归查询.而mysql中没有这种功能,但我们可以变通实现. 比如一个表: Table Name: tb_Tree Id | Parent ...
- Java线程池 ThreadPoolExecutor类
什么是线程池? java线程池是将大量的线程集中管理的类, 包括对线程的创建, 资源的管理, 线程生命周期的管理. 当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程, 从而减少系 ...
- ACM-最优配餐
题目描述: 最优配餐 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 栋栋最近开了一家餐饮连锁店,提供外卖服务.随着连锁店越来越多,怎么合理的给客户送餐成为了一个急需解决的问 ...
- 小米手机收到升级鸿蒙OS提示?官方回应
虽然尚未得到官方确认,但华为“鸿蒙”OS已经成为网络热门话题,在机圈引发热议. 本周,互联网上出现了显示为MIUI 10手机被锁定,屏幕上出现“小米将于2020年9月15日全面停止服务,届时您所有设备 ...
- USB2.0主机控制器 UPD720114 简单详解
UPD720114 是符合 USB 2.0规格的集线器控制器,适用于“符合生态原则的解决方案”.这种小型封装的控制器集成了核心逻辑电路的2.5 V 内部电压调整器.终端电阻器,减少了所需要的外部组件的 ...