zoukankan      html  css  js  c++  java
  • [BZOJ3160]万径人踪灭(FFT+Manacher)

    https://www.cnblogs.com/zhoushuyu/p/8672807.html

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     6 using namespace std;
     7 
     8 const int N=400010,mod=1e9+7;
     9 const double pi=acos(-1.);
    10 int n,len,ans,L,mx,id,bin[N],rev[N],f[N],p[N];
    11 char s[N],tmp[N];
    12 
    13 struct C{
    14     double x,y;
    15     C(double _x=0,double _y=0):x(_x),y(_y){}
    16     C operator +(C &b){ return C(x+b.x,y+b.y); }
    17     C operator -(C &b){ return C(x-b.x,y-b.y); }
    18     C operator *(C &b){ return C(x*b.x-y*b.y,x*b.y+b.x*y); }
    19 }a[N];
    20 
    21 void FFT(C a[],int f){
    22     for (int i=0; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
    23     for (int i=1; i<n; i<<=1){
    24         C wn=C(cos(pi/i),f*sin(pi/i));
    25         for (int p=i<<1,j=0; j<n; j+=p){
    26             C w(1,0);
    27             for (int k=0; k<i; k++,w=w*wn){
    28                 C x=a[j+k],y=w*a[i+j+k]; a[j+k]=x+y; a[i+j+k]=x-y;
    29             }
    30         }
    31     }
    32     if (f==-1) for (int i=0; i<n; i++) a[i].x/=n;
    33 }
    34 
    35 void work(char ch){
    36     for (int i=0; i<n; i++) a[i]=C(s[i]==ch,0);
    37     FFT(a,1); for (int i=0; i<n; i++) a[i]=a[i]*a[i]; FFT(a,-1);
    38     rep(i,2,len<<1) f[i]+=((int)(a[i].x+0.5)+1)/2;
    39 }
    40 
    41 int main(){
    42     freopen("bzoj3160.in","r",stdin);
    43     freopen("bzoj3160.out","w",stdout);
    44     scanf("%s",s+1); len=strlen(s+1);
    45     bin[0]=1; rep(i,1,len) bin[i]=(bin[i-1]<<1)%mod;
    46     for (n=1; n<=(len<<1); n<<=1) ++L;
    47     for (int i=0; i<n; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
    48     work('a'); work('b');
    49     rep(i,2,len<<1) ans=(ans+bin[f[i]]-1)%mod;
    50     rep(i,1,len) tmp[i]=s[i];
    51     s[0]='$'; s[1]='#';
    52     rep(i,1,len) s[i<<1]=tmp[i],s[(i<<1)|1]='#';
    53     rep(i,1,len<<1){
    54         p[i]=(mx>i) ? min(p[2*id-i],mx-i) : 1;
    55         while (s[i-p[i]]==s[i+p[i]]) p[i]++;
    56         if (i+p[i]>mx) mx=i+p[i],id=i;
    57     }
    58     rep(i,1,len<<1) ans=(ans-p[i]/2+mod)%mod;
    59     printf("%d
    ",ans);
    60     return 0;
    61 }
  • 相关阅读:
    P1012拼数
    P1622释放囚犯
    P1064 金明的预算方案
    P1754球迷购票问题
    卡塔兰数
    P1474货币系统
    P2562kitty猫基因
    P3984高兴的津津
    5-servlet简介
    java通过百度AI开发平台提取身份证图片中的文字信息
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9296417.html
Copyright © 2011-2022 走看看