• bzoj 4259: 残缺的字符串


      这题好神啊,居然是fft,表示一直在往数据结构上想。

      把'*'当成0,那么两个串可以匹配当且仅当$$sum (a[i]-b[i])^2 imes a[i] imes b[i]==0$$

      我们可以把平方拆开,然后就变成了几个乘积相加的形式,那就大力翻转一个串然后跑FFT。

      因为最开始MLE了所以复制粘贴了好多东西。

      

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define N 1200005
      7 #define M 300005
      8 #define pi acos(-1)
      9 #define E complex
     10 using namespace std;
     11 struct complex
     12 {
     13     double x,y;
     14     complex(double _x,double _y){x=_x;y=_y;}
     15     complex(){;}
     16     friend complex operator * (const complex &a,const complex &b)
     17     {
     18         complex c;c.x=a.x*b.x-a.y*b.y;c.y=a.x*b.y+a.y*b.x;return c;
     19     }
     20     friend complex operator / (complex a,double b)
     21     {
     22         return complex(a.x/b,a.y/b);
     23     }
     24     friend complex operator + (complex a,complex b)
     25     {
     26         return complex(a.x+b.x,a.y+b.y);
     27     }
     28     friend complex operator - (complex a,complex b)
     29     {
     30         return complex(a.x-b.x,a.y-b.y);
     31     }
     32 };
     33 int R[N];int n;
     34 void fft(E *a,int f)
     35 {
     36     for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
     37     for(int i=1;i<n;i<<=1)
     38     {
     39         E wn(cos(pi/i),f*sin(pi/i));
     40         for(int j=0;j<n;j+=(i<<1))
     41         {
     42             E w(1,0);
     43             for(int k=0;k<i;k++,w=w*wn)
     44             {
     45                 E x=a[j+k],y=w*a[j+k+i];
     46                 a[j+k]=x+y;a[j+k+i]=x-y;
     47             }
     48         }
     49     }
     50     if(f==-1)for(int i=0;i<n;i++)a[i]=a[i]/n;
     51 }
     52 int nn,mm;
     53 char s1[M],s2[M],s3[M];
     54 E a1[N],b1[N],c1[N];
     55 int ans[N];
     56 int st[M],top;
     57 int main()
     58 {
     59     scanf("%d%d",&nn,&mm);
     60     scanf("%s",s3);scanf("%s",s2);
     61     int l=0;
     62     for(n=1;n<2*mm;n<<=1)l++;
     63     for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(l-1));
     64     for(int i=0;i<nn;i++)s1[i]=s3[nn-i-1];
     65     for(int i=0;i<mm;i++)
     66     {
     67         int tmp=s2[i]-'a'+1;double p=tmp+0.0;
     68         if(s2[i]=='*')p=0;
     69         b1[i].x=p;
     70     }
     71     for(int i=0;i<nn;i++)
     72     {
     73         int tmp=s1[i]-'a'+1;double p=tmp+0.0;
     74         if(s1[i]=='*')p=0;
     75         a1[i].x=p*p*p;
     76     }
     77     fft(a1,1);fft(b1,1);
     78     for(int i=0;i<n;i++)c1[i]=a1[i]*b1[i];
     79     for(int i=0;i<n;i++)a1[i].x=a1[i].y=b1[i].x=b1[i].y=0;
     80     
     81     for(int i=0;i<mm;i++)
     82     {
     83         int tmp=s2[i]-'a'+1;double p=tmp+0.0;
     84         if(s2[i]=='*')p=0;
     85         b1[i].x=p*p;
     86     }
     87     for(int i=0;i<nn;i++)
     88     {
     89         int tmp=s1[i]-'a'+1;double p=tmp+0.0;
     90         if(s1[i]=='*')p=0;
     91         a1[i].x=p*p;
     92     }
     93     fft(a1,1);fft(b1,1);
     94     for(int i=0;i<n;i++)c1[i]=c1[i]-(a1[i]*b1[i]),c1[i]=c1[i]-(a1[i]*b1[i]);
     95     for(int i=0;i<n;i++)a1[i].x=a1[i].y=b1[i].x=b1[i].y=0;
     96 
     97     for(int i=0;i<mm;i++)
     98     {
     99         int tmp=s2[i]-'a'+1;double p=tmp+0.0;
    100         if(s2[i]=='*')p=0;
    101         b1[i].x=p*p*p;
    102     }
    103     for(int i=0;i<nn;i++)
    104     {
    105         int tmp=s1[i]-'a'+1;double p=tmp+0.0;
    106         if(s1[i]=='*')p=0;
    107         a1[i].x=p;
    108     }
    109     fft(a1,1);fft(b1,1);
    110     for(int i=0;i<n;i++)c1[i]=c1[i]+(a1[i]*b1[i]);
    111     
    112     fft(c1,-1);
    113 
    114     for(int i=nn-1;i<mm;i++)
    115     {
    116         if(fabs(c1[i].x)<0.5)
    117         {
    118             st[++top]=i-nn+2;
    119         }
    120     }
    121     printf("%d
    ",top);
    122     for(int i=1;i<=top;i++)
    123     {
    124         if(i!=top)printf("%d ",st[i]);
    125         else printf("%d
    ",st[i]);
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    GO语言面向对象06---面向对象练习01
    GO语言面向对象05---接口的多态
    GO语言面向对象04---接口的继承
    GO语言面向对象03---接口与断言
    GO语言面向对象02---继承
    Go语言练习---判断闰年以及根据现在的秒数求现在的年月日
    [操作系统] 线程管理
    [操作系统] 进程的状态
    [操作系统] 进程控制块
    关于这次计算机设计大赛
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6511727.html
Copyright © 2020-2023  润新知