• BZOJ3160 : 万径人踪灭


    答案=回文子序列数目-回文子串数目。

    回文子串数目可以通过Manacher在$O(n)$时间内求出。

    对于求回文子序列的数目,设f[i]为以i为对称中心的字符对数,则它对答案的贡献为$2^{f[i]}-1$。

    对于两个数$1leq ileq jleq n$,若a[i]==a[j],那么它们对f[i+j]有1点贡献。

    所以可以通过枚举当前字符,然后用FFT在$O(nlog n)$的时间内计算匹配带来的贡献。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=262144,P=1000000007;
    char a[N],s[N];int n,m,k,i,r,p,f[N],two[N],ans;
    struct comp{
      double r,i;comp(double _r=0,double _i=0){r=_r;i=_i;}
      comp operator+(const comp x){return comp(r+x.r,i+x.i);}
      comp operator-(const comp x){return comp(r-x.r,i-x.i);}
      comp operator*(const comp x){return comp(r*x.r-i*x.i,r*x.i+i*x.r);}
    }b[N],c[N];
    const double pi=acos(-1.0);
    void FFT(comp a[],int n,int t){
      for(int i=1,j=0;i<n-1;i++){
        for(int s=n;j^=s>>=1,~j&s;);
        if(i<j)swap(a[i],a[j]);
      }
      for(int d=0;(1<<d)<n;d++){
        int m=1<<d,m2=m<<1;
        double o=pi/m*t;comp _w(cos(o),sin(o));
        for(int i=0;i<n;i+=m2){
          comp w(1,0);
          for(int j=0;j<m;j++){
            comp &A=a[i+j+m],&B=a[i+j],t=w*A;
            A=B-t;B=B+t;w=w*_w;
          }
        }
      }
      if(t==-1)for(int i=0;i<n;i++)a[i].r/=n;
    }
    int main(){
      scanf("%s",a+1),n=std::strlen(a+1);
      for(two[0]=i=1;i<=n;i++)two[i]=(two[i-1]<<1)%P;
      for(i=1;i<=n;i++)s[i<<1]=a[i],s[i<<1|1]='#';s[0]='$',s[1]='#',s[m=(n+1)<<1]='@';
      for(f[1]=1,i=2;i<m;i++){
        for(f[i]=r>i?min(r-i,f[p*2-i]):1;s[i-f[i]]==s[i+f[i]];f[i]++);
        if(i+f[i]>r)r=i+f[i],p=i;
        ans=(ans-f[i]/2+P)%P;
      }
      for(k=1;k<=n;k<<=1);k<<=1;
      for(i=1;i<=n;i++){
        if(a[i]=='a')b[i].r=1;
        if(a[i]=='b')c[i].r=1;
      }
      FFT(b,k,1);FFT(c,k,1);
      for(i=0;i<k;i++)b[i]=b[i]*b[i]+c[i]*c[i];
      FFT(b,k,-1);
      for(i=0;i<k;i++)ans=(ans+two[((int)(b[i].r+0.5)+1)/2]-1)%P;
      return printf("%d",ans),0;
    }
    

      

  • 相关阅读:
    js面向对象和PHP面相对象
    git
    css3动画、2D与3D效果
    渲染数据方式
    ajax
    面向对象
    Date 日期
    Math 数值对象
    What is CGLib and JDK动态代理
    IDEA中lock对象不提示newCondition();
  • 原文地址:https://www.cnblogs.com/clrs97/p/4780581.html
Copyright © 2020-2023  润新知