BZOJ 3507 通配符匹配(贪心+hash或贪心+AC自动机)
首先可以对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自动机)的更多相关文章
- BZOJ3507 [Cqoi2014]通配符匹配 【哈希 + 贪心】
题目 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个 是星号(""'),可以匹配0个及以上的任意字符:另一个是问号(&quo ...
- 【BZOJ-3507】通配符匹配 DP + Hash
3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 372 Solved: 156[Submit][Statu ...
- [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)
显然f[i][j]表示S匹配到第i个通配符,T匹配到第j个字符,是否可行. 一次一起转移两个通配符之间的所有字符,Hash判断. 稍微有点细节.常数极大卡时过排名倒数,可能是没自然溢出的原因. #in ...
- [CQOI2014][bzoj3507] 通配符匹配 [字符串hash+dp]
题面 传送门 思路 0x01 KMP 一个非常显然而优秀的想法:把模板串按照'*'分段,然后对于每一段求$next$,'?'就当成可以对于任意字符匹配就行了 对于每个文本串,从前往后找第一个可以匹配的 ...
- BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)
题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...
- BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1902 Solved: 837[Submit][St ...
- 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序
[题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...
- BZOJ 2434 [Noi2011]阿狸的打字机(AC自动机)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [题目大意] 给出一个打印的过程,'a'-'z'表示输入字母,P表示打印该字符串 ...
- BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)
吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...
随机推荐
- WPF程序,运行时,结束时,要运行的操作(自动保存,检查单程序)
/// <summary> /// App.xaml 的交互逻辑 /// </summary> public partial class App : Application { ...
- 北京Uber优步司机奖励政策(2月26日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- RTL8188EUS之MAC地址烧写(使用利尔达模组)
1. 手上有几个RTL8188EUS的wifi模块,打算把台式机装个无线网卡,但是插上之后发现没有MAC,没办法只能自己去找个烧写MAC的软件.RTL8188内部有个eFuse,用来配置之类的.这个e ...
- 用Anko和Kotlin实现Android上的对话框和警告提示(KAD 24)
作者:Antonio Leiva 时间:Mar 9, 2017 原文链接:https://antonioleiva.com/dialogs-android-anko-kotlin/ 借助Builder ...
- Windows如何设置动态和静态ip地址
打开控制面板,一般在电脑的菜单栏能找到,win8和win10可以使用快捷键(win键+X键),找不到的朋友可以搜索一下. 进入到网络和共享中心,点击更改适配器设置. 这里显示的是电脑所以的网络 ...
- CSP201503-2:数字排序
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...
- 【第三章】Shell 变量的数值计算
一.算数运算符 shell中常见的算术运算符: shell中常见的算术命令: 1. 整数运算 方法一:expr expr命令就既可以用于整数运算,也可以用于相关字符串长度.匹配等的运算处理: exp ...
- SIG蓝牙mesh笔记2_mesh组成
目录 SIG 蓝牙 mesh 组成 mesh网络概述 网络和子网 设备和节点 devices & nodes 入网 mesh中的几个概念 智能插座例子 SIG 蓝牙 mesh 组成 mesh网 ...
- Python3 小工具-ICMP扫描
from scapy.all import * import optparse import threading import os def scan(ipt): pkt=IP(dst=ipt)/IC ...
- 安装sqoop 1.99.4
参考http://sqoop.apache.org/docs/1.99.4/Installation.html 1.简介 sqoop2分为server和client两部分.server作为maprde ...