首先可以对n个目标串单独进行处理。

对于每个目标串,考虑把模式串按'*'进行划分为cnt段。首尾两段一定得于原串进行匹配。剩下的cnt-2段尽量与最靠左的起点进行匹配。

对于剩下的cnt-2段。每段又可以通过‘?’划分为k个子串。对每个子串求出hash值。然后通过枚举起点与目标串的某个区间的hash进行判断。

就可以在O(k)的时间进行每一次的枚举了。对于目标串区间的hash值。可以通过预处理hash前缀进行O(1)询问。

而最多进行len次枚举。所以总复杂度为O(n*len*k).

另外判断子串匹配目标串的区间用AC自动机也是可以的。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
inline int Scan() {
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... char str[N], ss[N];
int hs[N], shs[N], xing[], pos, bg, ed;
struct Node{int x, len; bool flag;}node[]; int get_hash(int l, int r){return shs[r]-shs[l-]*hs[r-l+];}
bool check(int be, int L){
int sum=;
FOR(i,,L) if (node[i].flag) sum+=node[i].x; else sum+=node[i].len;
if (be+sum>ed+) return false;
FOR(i,,L) {
if (node[i].flag) be+=node[i].x;
else {
if (get_hash(be,be+node[i].len-)!=node[i].x) return false;
be+=node[i].len;
}
}
return true;
}
bool sol(){
int num, sum, l, cnt, ll;
FOR(i,,pos) {
if (xing[i]-xing[i-]<=) continue;
sum=num=l=ll=cnt=;
FOR(j,xing[i-]+,xing[i]-) {
if (str[j]=='?') {
++num;
if (l) node[++cnt].x=sum, node[cnt].len=l; node[cnt].flag=, sum=l=;
}
else {
sum=sum*MOD+str[j]; ++l;
if (num) node[++cnt].x=num, node[cnt].flag=, num=;
}
}
if (l) node[++cnt].x=sum, node[cnt].len=l; node[cnt].flag=, sum=l=;
if (num) node[++cnt].x=num, node[cnt].flag=, num=;
while (bg<=ed&&!check(bg,cnt)) ++bg;
if (!check(bg,cnt)) return false;
FOR(i,,cnt) if (node[i].flag) ll+=node[i].x; else ll+=node[i].len;
bg+=ll;
}
return true;
}
int main ()
{
hs[]=; FO(i,,N) hs[i]=hs[i-]*MOD;
scanf("%s",str+);
int T;
scanf("%d",&T);
while (T--) {
scanf("%s",ss+);
pos=; bg=; ed=strlen(ss+);
for (int i=; ss[i]; ++i) shs[i]=shs[i-]*MOD+ss[i];
int l=, r=strlen(str+);
int flag=;
while (str[l]!='*'&&l<=r&&bg<=ed) {
if (str[l]=='?'||str[l]==ss[bg]) ++l, ++bg;
else {flag=; break;}
}
while (str[r]!='*'&&l<=r&&bg<=ed) {
if (str[r]=='?'||str[r]==ss[ed]) --r, --ed;
else {flag=; break;}
}
if (flag) {puts("NO"); continue;}
FOR(i,l,r) if (str[i]=='*') xing[++pos]=i;
if (pos==&&bg<=ed) {puts("NO"); continue;}
puts(sol()?"YES":"NO");
}
return ;
}

BZOJ 3507 通配符匹配(贪心+hash或贪心+AC自动机)的更多相关文章

  1. BZOJ3507 [Cqoi2014]通配符匹配 【哈希 + 贪心】

    题目 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个 是星号(""'),可以匹配0个及以上的任意字符:另一个是问号(&quo ...

  2. 【BZOJ-3507】通配符匹配 DP + Hash

    3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 372  Solved: 156[Submit][Statu ...

  3. [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)

    显然f[i][j]表示S匹配到第i个通配符,T匹配到第j个字符,是否可行. 一次一起转移两个通配符之间的所有字符,Hash判断. 稍微有点细节.常数极大卡时过排名倒数,可能是没自然溢出的原因. #in ...

  4. [CQOI2014][bzoj3507] 通配符匹配 [字符串hash+dp]

    题面 传送门 思路 0x01 KMP 一个非常显然而优秀的想法:把模板串按照'*'分段,然后对于每一段求$next$,'?'就当成可以对于任意字符匹配就行了 对于每个文本串,从前往后找第一个可以匹配的 ...

  5. BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)

    题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...

  6. BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1902  Solved: 837[Submit][St ...

  7. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    [题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...

  8. BZOJ 2434 [Noi2011]阿狸的打字机(AC自动机)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [题目大意] 给出一个打印的过程,'a'-'z'表示输入字母,P表示打印该字符串 ...

  9. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)

    吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...

随机推荐

  1. tarjan算法求最近公共祖先

    tarjian算法 LCA: LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通往根的道路上,肯定会有公共的节点,我们 ...

  2. 韩国KT软件NB-IOT开发记录V150(2)IOT maker通信相关

    1. 测试的AT指令,创建端口和IP地址链接 AT#IMINIT=," 开始连接 AT#IMCONN 创建object ID AT#IMOBJMETA=,," 发送数据 AT#IM ...

  3. 天嵌IMX6开发板测试-第一篇

    1.看下开发板介绍 品牌: 天嵌 CPU型号: NXP i.MX6Q 架构: Cortex_A9 主频: *1GHz 内存: 2GB DDR3 存储: 8GB eMMC FLA(64GB可扩) 2. ...

  4. eclipse+tomcat配置远程debug调整

    由于开发环境与真实服务器环境存在差异,有时开发时明明正常的逻辑,部署之后就会出现各种各样的问题,通过日志邮不能明确定位到问题的时候,可以采用远程debug调试来定位问题.下面就介绍一下具体的配置步骤: ...

  5. 基于Docker的UI自动化初探

    本文来自网易云社区 前言 一直以来,项目迭代的时间都是比较紧张的,开发加班加点coding,测试加班加点提bug.都说"时间像海绵里的水,挤挤总会有的"(当然这里的"挤挤 ...

  6. 【独家】K8S漏洞报告 | 近期bug fix解读&1.9.11主要bug fix汇总

    *内容提要: 1. Kube-proxy长连接优雅断开机制及IPVS模式实现 2. 10/29--11/19 bug fix汇总分析 3. 1.9.11重要bug fix汇总 在本周的跟踪分析中,以1 ...

  7. uvaoj 101 - The Blocks Problem(vector应用+技巧)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=835&page= ...

  8. CryptoZombies学习笔记——Lesson3

    第三课就开始深入讲解solidity编程技巧了. chapter1: 智能合约的不变性. 合约一旦部署到以太坊后,就不可更改了,所以从一方面来说,智能合约代码的安全性是如此重要,因为一旦发现你的代码里 ...

  9. parity 注记词

    spousal tint untold around rosy daintily unrated sheep choice showpiece chirping gala

  10. POJ 3608 Bridge Across Islands(计算几何の旋转卡壳)

    Description Thousands of thousands years ago there was a small kingdom located in the middle of the ...