• bzoj 4503 两个串 fft


    两个串

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 1078  Solved: 434
    [Submit][Status][Discuss]

    Description

    兔子们在玩两个串的游戏。给定两个字符串S和T,兔子们想知道T在S中出现了几次,
    分别在哪些位置出现。注意T中可能有“?”字符,这个字符可以匹配任何字符。

    Input

    两行两个字符串,分别代表S和T

    Output

    第一行一个正整数k,表示T在S中出现了几次
    接下来k行正整数,分别代表T每次在S中出现的开始位置。按照从小到大的顺序输出,S下标从0开始。

    Sample Input

    bbabaababaaaaabaaaaaaaabaaabbbabaaabbabaabbbbabbbbbbabbaabbbababababbbbbbaaabaaabbbbbaabbbaabbbbabab
    a?aba?abba

    Sample Output

    0

    HINT

    S 长度不超过 10^5, T 长度不会超过 S。 S 中只包含小写字母, T中只包含小写字母和“?”

     
    题解:判断两个串,第二个在第一个中出现次数,这类问题ac自动机,kmp
       但是第二个串有通配符,这个应该怎么办,其实可以这样判,就是对于
       这个就是个卷积的形式,对于通配符就是如果是的话就直接为0,就是再乘个数的问题吧,将第二个串反一下就是个卷积了。
     1 #include<cstring>
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 
     7 #define ll long long
     8 #define N 100007
     9 #define pi acos(-1)
    10 using namespace std;
    11 inline int read()
    12 {
    13     int x=0,f=1;char ch=getchar();
    14     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    15     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 
    19 int n,m,res,num,L;
    20 double hjq;
    21 int c[N],d[N],rev[N];
    22 ll ans[N<<2];
    23 char ch[N];
    24 
    25 struct comp
    26 {
    27     double r,v;
    28     comp(){}
    29     comp(double a,double b){r=a,v=b;}
    30     friend inline comp operator+(comp x,comp y){return comp(x.r+y.r,x.v+y.v);}
    31     friend inline comp operator-(comp x,comp y){return comp(x.r-y.r,x.v-y.v);}
    32     friend inline comp operator*(comp x,comp y){return comp(x.r*y.r-x.v*y.v,x.r*y.v+x.v*y.r);}
    33 }a1[N<<2],b1[N<<2],a2[N<<2],b2[N<<2],fzy[N<<2];
    34 
    35 void FFT(comp *a,int flag)
    36 {
    37     for (int i=0;i<num;i++)
    38         if (i<rev[i]) swap(a[i],a[rev[i]]);
    39     for (int i=1;i<num;i<<=1)
    40     {
    41         comp wn=comp(cos(pi/i),flag*sin(pi/i));
    42         for (int j=0;j<num;j+=(i<<1))
    43         {
    44             comp w=comp(1,0);
    45             for (int k=0;k<i;k++,w=w*wn)
    46             {
    47                 comp x=a[j+k],y=w*a[j+k+i];
    48                 a[j+k]=x+y,a[j+k+i]=x-y;
    49             }
    50         }
    51     }
    52     if (flag==-1) for (int i=0;i<num;i++) a[i].r/=num; 
    53 }
    54 int main()
    55 {
    56     scanf("%s",ch),n=strlen(ch);
    57     for (int i=0;i<n;i++) c[i]=ch[i]-'a'+1;
    58     scanf("%s",ch),m=strlen(ch);
    59     for (int i=0;i<m;i++) d[i]=(ch[m-i-1]=='?')?0:ch[m-i-1]-'a'+1;
    60     
    61     for (int i=0;i<n;i++) a1[i].r=1.0*c[i]*c[i];
    62     for (int i=0;i<m;i++) b1[i].r=1.0*d[i];
    63     for (int i=0;i<n;i++) a2[i].r=-2.0*c[i];
    64     for (int i=0;i<m;i++) b2[i].r=1.0*d[i]*d[i];
    65     for (int i=0;i<m;i++) hjq+=d[i]*d[i]*d[i];
    66     
    67     
    68     for (num=1;num<=n+m-1;num<<=1,L++);if (L) L--;
    69     for (int i=0;i<num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
    70     FFT(a1,1),FFT(b1,1),FFT(a2,1),FFT(b2,1);
    71     for (int i=0;i<num;i++) fzy[i]=a1[i]*b1[i]+a2[i]*b2[i];
    72     FFT(fzy,-1);
    73     for (int i=0;i<num;i++) ans[i]=(ll)(hjq+fzy[i].r+0.5);
    74     for (int i=m-1;i<n;i++) if (!ans[i]) res++;
    75     printf("%d
    ",res);
    76     for (int i=m-1;i<n;i++)
    77         if (!ans[i]) printf("%d
    ",i-m+1);
    78 }
  • 相关阅读:
    1、C#多线程基础理论
    ASP.NET MVC过滤器学习笔记
    C# 虚方法
    asp.net面试题总结1(未完待续。。。。)
    Linux高级调试与优化——进程管理和调度
    Linux高级调试与优化——内存管理
    Linux高级调试与优化——用户态堆
    Linux高级调试与优化——信号量机制与应用程序崩溃
    Linux高级调试与优化——gdb调试命令
    Nor Flash芯片特性分析
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8681978.html
Copyright © 2020-2023  润新知