bzoj4259 残缺的字符串

原创 2018年04月15日 16:37:41

http://www.elijahqi.win/archives/3098
Description

很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n。可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺。
你想对这两个串重新进行匹配,其中A为模板串,那么现在问题来了,请回答,对于B的每一个位置i,从这个位置开始连续m个字符形成的子串是否可能与A串完全匹配?

Input

第一行包含两个正整数m,n(1<=m<=n<=300000),分别表示A串和B串的长度。
第二行为一个长度为m的字符串A。
第三行为一个长度为n的字符串B。
两个串均仅由小写字母和号组成,其中号表示相应位置已经残缺。

Output

第一行包含一个整数k,表示B串中可以完全匹配A串的位置个数。
若k>0,则第二行输出k个正整数,从小到大依次输出每个可以匹配的开头位置(下标从1开始)。

Sample Input

3 7
a*b
aebr*ob
Sample Output

2
1 5
HINT

Source

By Claris

orz fft 字符串匹配 好那么

如果把两个串’*’的部分当成0那么
有如下公式 i(a[i]b[i])2a[i]b[i]=0 这个为什么一定要平方 因为有可能存在一些情况 比如 前面是负数然后后面是整数结果我这里恰好加成0了但是显然是不匹配的.. 然后针对这个式子把a反转一下 然后公式写出来化简一下发现其中分成三段每一段分别是卷积形式 所以就fft一下 最后看一下每位上是否为0 即可

#include<cmath>
#include<cstdio>
#include<cstring>
#define pi acos(-1)
#include<algorithm>
using namespace std;
const int N=300030;
struct C{
    double r,i;
    inline friend C operator +(const C &a,const C &b){return (C){a.r+b.r,a.i+b.i};}
    inline friend C operator -(const C &a,const C &b){return (C){a.r-b.r,a.i-b.i};}
    inline friend C operator *(const C &a,const C &b){return (C){a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r};}
    inline void operator *=(const C &a){*this=*this*a;}
}a[N<<2],b[N<<2],c[N<<2];
char ss1[N],s2[N];
int pend[N],ans,n,m,a1[N<<2],a2[N<<2],R[N<<2];
inline void fft(C *x,int f){
    for (int i=0;i<n;++i) if (i<R[i]) swap(x[i],x[R[i]]);
    for (int i=1;i<n;i<<=1){
        C wn=(C){cos(pi/i),f*sin(pi/i)};
        for (int j=0;j<n;j+=i<<1){
            C w=(C){1,0},t1,t2;
            for (int k=0;k<i;++k,w*=wn)
                t1=x[j+k],t2=x[j+i+k]*w,x[j+k]=t1+t2,x[j+i+k]=t1-t2;
        }
    }if (f==-1) for (int i=0;i<n;++i) x[i].r/=n;
}
int main(){
    freopen("bzoj4259.in","r",stdin);
    scanf("%d%d",&m,&n);scanf("%s",ss1);scanf("%s",s2);int nn=n;
    for (int i=0;i<m;++i) a1[i]=ss1[m-i-1]!='*'?ss1[m-i-1]-'a'+1:0;
    for (int i=0;i<n;++i) a2[i]=s2[i]!='*'?s2[i]-'a'+1:0;m+=n;int t=0;
    for (n=1;n<m;n<<=1,++t);for (int i=0;i<n;++i) R[i]=(R[i>>1]>>1)|(i&1)<<t-1;
    for (int i=0;i<n;++i) a[i]=(C){a1[i]*a1[i]*a1[i],0},b[i]=(C){a2[i],0};
    fft(a,1);fft(b,1);for (int i=0;i<n;++i) c[i]=c[i]+a[i]*b[i];m-=nn;
    for (int i=0;i<n;++i) a[i]=(C){a1[i]*a1[i],0},b[i]=(C){a2[i]*a2[i],0};
    fft(a,1);fft(b,1);for (int i=0;i<n;++i) c[i]=c[i]-(C){2,0}*a[i]*b[i];
    for (int i=0;i<n;++i) a[i]=(C){a1[i],0},b[i]=(C){a2[i]*a2[i]*a2[i],0};
    fft(a,1);fft(b,1);for (int i=0;i<n;++i) c[i]=c[i]+a[i]*b[i];fft(c,-1);
    for (int i=m-1;i<nn;++i) if (c[i].r<0.5) ++ans,pend[ans]=i+1-m+1;
    printf("%d\n",ans);for (int i=1;i<=ans;++i) printf("%d ",pend[i]);
    return 0;
}
版权声明:辣鸡蒟蒻的blog https://blog.csdn.net/elijahqi/article/details/79950526

[BZOJ4259] 残缺的字符串 (FFT)

题意:定义*号可匹配任意字符。给出A串,B串,求A串在B中完全匹配的所有位置。 将*号视作0,则两个等长的串可匹配当且仅当Σ(a[i]-b[i])^2*a[i]*b[i]==0。将A串和B串最左边对...
  • u011542204
  • u011542204
  • 2016-02-21 17:42:54
  • 1397

[BZOJ4259]残缺的字符串

题目大意给定模板串AA和母串BB,长度分别为mm和nn,你需要统计模板串在母串中所有出现的位置。 字符集都是小写拉丁字母,而且存在通配符∗*能够匹配任意字符。1≤m,n≤3×1051\le m,n\...
  • a_crazy_czy
  • a_crazy_czy
  • 2017-04-22 22:06:06
  • 264

bzoj 4259 残缺的字符串

题目:bzoj4259 残缺的字符串 洛谷无需权限 今天刚学的fft,于是专门找的这类题; 由于知道算法是什么,就奔着fft上想了; 比较容易就能得出,如果将模板串翻转位置之后...
  • qq_36284842
  • qq_36284842
  • 2018-02-12 21:09:06
  • 59

[BZOJ4259]残缺的字符串(FFT)

题目描述传送门题目大意:给出一个模板串和一个母串,问模板串在母串中出现过几次。带通配符。题解这道题和两个串那道题是差不多的。。 令F(i)表示将模板串的最后一个怼到母串的第i个是否能匹配,0表示能匹...
  • Clove_unique
  • Clove_unique
  • 2017-04-24 10:40:06
  • 430

bzoj4259: 残缺的字符串

FFT
  • FSAHFGSADHSAKNDAS
  • FSAHFGSADHSAKNDAS
  • 2017-04-20 21:42:57
  • 291

bzoj 4259: 残缺的字符串 (FFT)

题目描述传送门题目大意:给出两个带通配符的字符串,求匹配的个数。题解FFT裸题,通配符的位置赋值成0 f[i]=∑j=1n(g[j]−h[i−j])2∗g[j]∗h[i−j]f[i]=\sum\li...
  • clover_hxy
  • clover_hxy
  • 2017-03-17 09:58:16
  • 263

bzoj4259 残缺的字符串

http://www.elijahqi.win/archives/3098 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m...
  • elijahqi
  • elijahqi
  • 2018-04-15 16:37:41
  • 17

BZOJ4259: 残缺的字符串

一直在想各种字符串匹配算法… 将’a’视为1,’b’视为2,‘*’视为0 那么A0......AnA0......AnA_0......A_n和Bk.....Bk+n−1Bk.....Bk+n−1...
  • L_0_Forever_LF
  • L_0_Forever_LF
  • 2018-03-05 16:55:25
  • 48

BZOJ 4259 残缺的字符串

FFT+神奇的表达方式
  • SenyeLicone
  • SenyeLicone
  • 2017-03-08 11:02:30
  • 217

带中文的字符串数据写入文件出现数据残缺

场景:(UTF-8编码)将字符串写入文件,当字符串中包含中文时,出现写入文件的数据残缺,而当不包含中文时,写入文件的数据正常。示例:String str = &quot;fadsfdsf212&quo...
  • qq_22158021
  • qq_22158021
  • 2018-02-26 15:02:25
  • 14
收藏助手
不良信息举报
您举报文章:bzoj4259 残缺的字符串
举报原因:
原因补充:

(最多只允许输入30个字)