zoukankan      html  css  js  c++  java
  • BZOJ 3160: 万径人踪灭

    题解

    算出所有的回文子序列减去连续的

    先在中间插好*

    用f[i]表示以i为对称中心的对称位置有多少对

    位置i的贡献为2f[i]-1

    然后用manacher算不合法的

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 using namespace std;
      6 const int maxn=600009;
      7 const double pi=acos(-1.0);
      8 const int mm=1000000007;
      9 
     10 int n;
     11 char T[maxn];
     12 long long ans=0;
     13 long long ft[maxn];
     14 
     15 struct Cpx{
     16     double x,y;
     17     Cpx(){
     18         x=y=0.0;
     19     }
     20     Cpx(double xx,double yy){
     21         x=xx;y=yy;
     22     }
     23 }Pa[maxn];
     24 
     25 Cpx operator + (Cpx z1,Cpx z2){
     26     return Cpx(z1.x+z2.x,z1.y+z2.y);
     27 }
     28 Cpx operator - (Cpx z1,Cpx z2){
     29     return Cpx(z1.x-z2.x,z1.y-z2.y);
     30 }
     31 Cpx operator * (Cpx z1,Cpx z2){
     32     return Cpx(z1.x*z2.x-z1.y*z2.y,z1.x*z2.y+z2.x*z1.y);
     33 }
     34 
     35 int rev[maxn]={0};
     36 void FFT(Cpx *arr,int n,int f){
     37     int b=0;
     38     for(int len=1;len<n;len<<=1)b++;
     39     for(int i=0;i<n;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(b-1));
     40     
     41     for(int i=0;i<n;++i)if(i<rev[i])swap(arr[i],arr[rev[i]]);
     42     
     43     for(int k=1;k<n;k<<=1){
     44         int p=k+k;
     45         Cpx wn=Cpx(cos(pi/k),f*sin(pi/k));
     46         for(int i=0;i<n;i+=p){
     47             Cpx w=Cpx(1.0,0.0);
     48             for(int j=0;j<k;++j,w=w*wn){
     49                 Cpx x=arr[i+j],y=w*arr[i+j+k];
     50                 arr[i+j]=x+y;
     51                 arr[i+j+k]=x-y;
     52             }
     53         }
     54     }
     55     if(f==-1){
     56         for(int i=0;i<n;++i)arr[i].x=arr[i].x/(n*1.0);
     57     }
     58 }
     59 
     60 
     61 char s[maxn];
     62 int p[maxn]={0};
     63 void Manacher(int n){
     64     int mxlen=0,mxpla=0;
     65     for(int i=1;i<=n;++i){
     66         if(mxpla+mxlen>i){
     67             p[i]=min(mxpla+mxlen-i,p[mxpla*2-i]);
     68         }
     69         while(s[i-p[i]]==s[i+p[i]])++p[i];
     70         if(i+p[i]>mxpla+mxlen){
     71             mxpla=i;mxlen=p[i];
     72         }
     73     }
     74 }
     75 
     76 int f[maxn];
     77 
     78 int main(){
     79     scanf("%s",T+1);
     80     int len=strlen(T+1);
     81     s[++n]='*';
     82     for(int i=1;i<=len;++i){
     83         s[++n]=T[i];
     84         s[++n]='*';
     85     }
     86     s[++n]='#';
     87     
     88     
     89     for(len=1;len<=(n*2);len<<=1);
     90     for(int i=0;i<len;++i){
     91         Pa[i].x=Pa[i].y=0.0;
     92         if(s[i]=='a')Pa[i].x=1.0;
     93     }
     94 //    for(int i=0;i<len;++i)cout<<Pa[i].x<<' ';
     95 //    cout<<endl;
     96     FFT(Pa,len,1);
     97     
     98     for(int i=0;i<len;++i)Pa[i]=Pa[i]*Pa[i];
     99     FFT(Pa,len,-1);
    100 //    for(int i=0;i<len;++i)printf("%.0f ",Pa[i].x);
    101 //    cout<<endl;
    102     for(int i=1;i<=n;++i){
    103         int t=(int)(Pa[i*2].x+0.5);
    104         f[i]+=(t+1)/2;
    105     }
    106     
    107     for(int i=0;i<len;++i){
    108         Pa[i].x=Pa[i].y=0.0;
    109         if(s[i]=='b')Pa[i].x=1.0;
    110     }
    111     FFT(Pa,len,1);
    112     for(int i=0;i<len;++i)Pa[i]=Pa[i]*Pa[i];
    113     FFT(Pa,len,-1);
    114     for(int i=1;i<=n;++i){
    115         int t=(int)(Pa[i*2].x+0.5);
    116         f[i]+=(t+1)/2;
    117     }
    118     
    119     Manacher(n);
    120     
    121 //    for(int i=1;i<=n;++i)cout<<p[i]<<' ';
    122 //    cout<<endl;
    123     
    124     ft[0]=1;
    125     for(int i=1;i<=n;++i)ft[i]=(ft[i-1]<<1)%mm;
    126     for(int i=1;i<=n;++i){
    127         ans=(ans+ft[f[i]]-1+mm)%mm;
    128         ans=(ans-p[i]/2+mm)%mm;
    129     }
    130     
    131     cout<<ans<<endl;
    132     return 0;
    133 }
  • 相关阅读:
    剑指offer面试题17:合并两个排序的链表
    剑指offer面试题16:反转链表
    剑指offer面试题15:链表中倒数第K个节点
    Jinja2.template渲染两种常见用法
    hadoop集群运维碰到的问题汇总
    hbase配置参数总结
    hbase内核学习总结
    zookeeper学习笔记
    mongodb 3.2性能测试
    kafka内部结构笔记
  • 原文地址:https://www.cnblogs.com/zzyer/p/8970742.html
Copyright © 2011-2022 走看看