[BZOJ4259]残缺的字符串
Description:
给定两个带通配符的串,求可能出现几次匹配,以及这些匹配位置
Hint:
\(n \le 3*10^5\)
Solution:
定义匹配函数 \(P(x)=\sum_{i=x}^{x+m}(S1[i]-S2[i])^2*S1[i]*S2[i]\)
展开的式子太长,有时间再放
大概是一堆字符串卷积
翻转后FFT即可
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=2e6+5;
const double PI=acos(-1);
int n,m,l,tot,lim=1,a[mxn],b[mxn],r[mxn],q[mxn];
ll s[mxn];
char s1[mxn],s2[mxn];
inline int read() {
    char c=getchar(); int x=0,f=1;
    while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
    return x*f;
}
inline int chkmax(register int &x,register int y) {if(x<y) x=y;}
inline int chkmin(register int &x,register int y) {if(x>y) x=y;}
struct ed {
    int to,nxt;
}t[mxn<<1];
struct cp {
    double x,y;
    cp (double xx=0,double yy=0) {x=xx;y=yy;}
    friend cp operator + (cp a,cp b) {
        return cp(a.x+b.x,a.y+b.y);
    }
    friend cp operator - (cp a,cp b) {
        return cp(a.x-b.x,a.y-b.y);
    }
    friend cp operator * (cp a,cp b) {
        return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
    }
}A[mxn],B[mxn],C[mxn];
void FFT(cp *p,register int opt)
{
    for(register int i=0;i<lim;++i)
        if(i<r[i]) swap(p[i],p[r[i]]);
    for(register int mid=1;mid<lim;mid<<=1) {
        cp wn=cp(cos(PI/mid),opt*sin(PI/mid));
        for(register int len=mid<<1,j=0;j<lim;j+=len) {
            cp w=cp(1,0);
            for(register int k=0;k<mid;++k,w=w*wn) {
                cp x=p[j+k],y=w*p[j+mid+k];
                p[j+k]=x+y; p[j+mid+k]=x-y;
            }
        }
    }
}
int main()
{
    scanf("%d%d%s%s",&m,&n,s1,s2);
    for(register int i=0,j=m-1;i<j;++i,--j) swap(s1[i],s1[j]);
    for(register int i=0;i<m;++i) if(s1[i]!='*') a[i]=s1[i]-'a'+1;
    for(register int i=0;i<n;++i) if(s2[i]!='*') b[i]=s2[i]-'a'+1;
    while(lim<=n+m) ++l,lim<<=1;
    for(register int i=0;i<lim;++i)
        r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    for(register int i=0;i<=lim;++i)
        A[i]=cp(a[i]*a[i]*a[i],0),B[i]=cp(b[i],0);
    FFT(A,1); FFT(B,1);
    for(register int i=0;i<=lim;++i) C[i]=A[i]*B[i];
    FFT(C,-1);
    for(register int i=0;i<=lim;++i) s[i]+=(ll)(C[i].x/lim+0.5);
    for(register int i=0;i<=lim;++i)
        A[i]=cp(a[i],0),B[i]=cp(b[i]*b[i]*b[i],0);
    FFT(A,1); FFT(B,1);
    for(register int i=0;i<=lim;++i) C[i]=A[i]*B[i];
    FFT(C,-1);
    for(register int i=0;i<=lim;++i) s[i]+=(ll)(C[i].x/lim+0.5);
    for(register int i=0;i<=lim;++i)
        A[i]=cp(a[i]*a[i],0),B[i]=cp(b[i]*b[i],0);
    FFT(A,1); FFT(B,1);
    for(register int i=0;i<=lim;++i) C[i]=A[i]*B[i];
    FFT(C,-1);
    for(register int i=0;i<=lim;++i) s[i]-=2*(ll)(C[i].x/lim+0.5);
    for(register int i=m-1;i<n;++i) if(s[i]==0) q[++tot]=i-m+2;
    printf("%d\n",tot);
    for(register int i=1;i<=tot;++i) printf("%d ",q[i]);
    return 0;
}
												
											[BZOJ4259]残缺的字符串的更多相关文章
- CF528D Fuzzy Search 和 BZOJ4259 残缺的字符串
		
Fuzzy Search 给你文本串 S 和模式串 T,求 S 的每个位置是否能模糊匹配上 T. 这里的模糊匹配指的是把 T 放到 S 相应位置上之后,T 中每个字符所在位置附近 k 个之内的位置上的 ...
 - BZOJ4259残缺的字符串
		
题目描述 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. ...
 - BZOJ4259 残缺的字符串(FFT)
		
两个串匹配时相匹配的位置位置差是相同的,那么翻转一个串就变成位置和相同,卷积的形式. 考虑如何使用卷积体现两个位置能否匹配.一个暴力的思路是每次只考虑一种字符,将其在一个串中设为1,并在另一个串中将不 ...
 - BZOJ4259:残缺的字符串(FFT)
		
Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同 ...
 - BZOJ4259 残缺的字符串 【fft】
		
题目 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想 ...
 - BZOJ4259: 残缺的字符串 & BZOJ4503: 两个串
		
[传送门:BZOJ4259&BZOJ4503] 简要题意: 给出两个字符串,第一个串长度为m,第二个串长度为n,字符串中如果有*字符,则代表当前位置可以匹配任何字符 求出第一个字符串在第二个字 ...
 - BZOJ4259 残缺的字符串 多项式 FFT
		
原文链接http://www.cnblogs.com/zhouzhendong/p/8798532.html 题目传送门 - BZOJ4259 题意 给你两个串,用其中一个来匹配另一个.问从母串的那些 ...
 - 2018.11.17 bzoj4259: 残缺的字符串(fft)
		
传送门 fftfftfft套路题. 我们把aaa ~ zzz映射成111 ~ 262626,然后把∗*∗映射成000. 考虑对于两个长度都为nnn的字符串A,BA,BA,B. 我们定义一个差异函数di ...
 - BZOJ4259: 残缺的字符串(FFT 字符串匹配)
		
题意 题目链接 Sol 知道FFT能做字符串匹配的话这就是个裸题了吧.. 考虑把B翻转过来,如果\(\sum_{k = 0}^M (B_{i - k} - A_k)^2 * B_{i-k}*A_k = ...
 
随机推荐
- ffmpeg切割视频
			
using System.Diagnostics; public static void carveVideo() { var inputpath = @"d:\1.mp4"; v ...
 - python requests的content和text方法的区别
			
requests对象的get和post方法都会返回一个Response对象,这个对象里面存的是服务器返回的所有信息,包括响应头,响应状态码等.其中返回的网页部分会存在.content和.text两个对 ...
 - webpack学习笔记--提取公共代码
			
为什么需要提取公共代码 大型网站通常会由多个页面组成,每个页面都是一个独立的单页应用. 但由于所有页面都采用同样的技术栈,以及使用同一套样式代码,这导致这些页面之间有很多相同的代码. 如果每个页面的代 ...
 - Jmeter入门(压力测试)
			
Jmeter介绍 Jmeter是一款使用Java开发的,开源免费的,测试工具, 主要用来做功能测试和性能测试(压力测试/负载测试). 而且用Jmeter 来测试 Restful API, 非常好用. ...
 - Python 高级面向对象
			
一.字段 1.字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同. a.普通字段属于对象(实例变量) b.静态字段属于类(类变量) 二.属性 对于属性,有以 ...
 - 2018牛客网暑假ACM多校训练赛(第四场)D Another Distinct Values 构造
			
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round4-D.html 题目传送门 - https://www.no ...
 - JDK5的新特性之增强for循环遍历数组或集合
			
[格式] for(元素的类型 变量名 : 数组或Collection集合名){ //此处使用变量名即可,该变量就是普通for里的i. }
 - byte数据常量池问题
			
[代码] public class BufferPoolDemo { public static void main(String[] args) { Integer i1=127; Integer ...
 - 解析eBay BASE模式、去哪儿及蘑菇街分布式架构
			
目录:问题分析概念解读Most Simple原理解读eBey.去哪儿.蘑菇街分布式事务案例分析 参考资料 1.问题解析 要想做架构,必须识别出问题,即是谁的问题,什么问题.明显的,分布式架构解决 ...
 - Redis的工作流程
			
从图上可以看出,当一个客户端访问服务器的时候,客户端请求会先到达Nginx,由Nginx负责对数据进行分发,上传到多个服务器,当用户访问到tomcat1的时候,会进行登陆验证并将session放入se ...