zoukankan      html  css  js  c++  java
  • 【BZOJ3160】万径人踪灭

    fft劲啊

    题目太长,拒绝帖原题

    一句话题意:

    给一个ab串,求不连续的回文子序列的个数

    看zars19的题解(和代码)写出来的

    恩,回文子序列满足个性质,假设s[i]==s[j],他们的中点是mid

    那么i+j==mid*2

    卷积!

    a设为1,b设为0自己卷一下,然后反过来b为1_a为0再卷一下

    卷出来的a[i]表示以i为中心的最长回文子序列的长度

    大概是酱紫:

    判重的话(a[i]+1)/2就可以辣

    但是这题目要求是不连续的回文子序列,fft搞出来的会有连续的

    所以马拉车搞一搞,减去连续的回文子串即可

    原来fft要开4倍,因为卷积卷完后差不多会增长一倍……(比如乘法是吧,手玩一下

    注意马拉车也要开两倍

    数组没开够没有1A

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 #define ll long long
     8 const int dalao=1000000007;
     9 struct cp{
    10     double r,i;
    11     cp(double _r=0,double _i=0):  r(_r),i(_i){}
    12     cp operator+(cp x){return cp(r+x.r,i+x.i);}
    13     cp operator-(cp x){return cp(r-x.r,i-x.i);}
    14     cp operator*(cp x){return cp(r*x.r-i*x.i,r*x.i+i*x.r);}
    15 };
    16 char s[410000],ss[410000];  int n,nn;
    17 cp a[410000],b[410000],tmp[410000];
    18 int rvs[410000],dig[410000],N,L;
    19 int f[410000];
    20 void fft(cp x[],int mk){
    21     for(int i=0;i<N;++i)  tmp[i]=x[rvs[i]];
    22     for(int i=0;i<N;++i)  x[i]=tmp[i];
    23     cp _x,_y,wn,w;
    24     for(int i=2;i<=N;i<<=1){
    25         wn=cp(cos(2*M_PI/i),mk*sin(2*M_PI/i));
    26         for(int k=0;k<N;k+=i){
    27             w=cp(1,0);
    28             for(int j=k;j<k+i/2;++j){
    29                 _x=x[j];  _y=x[j+i/2]*w;
    30                 x[j]=_x+_y;  x[j+i/2]=_x-_y;
    31                 w=w*wn;
    32             }
    33         }
    34     }
    35     if(mk==-1)  for(int i=0;i<N;++i)  x[i].r/=N;
    36 }
    37 ll mnch(){
    38     memset(f,0,sizeof(f));
    39     int mx=0,id=0;  ll bwl=0;
    40     for(int i=0;i<n;++i)  ss[i<<1]='#',ss[i<<1|1]=s[i];
    41     ss[nn-1]='#';
    42     for(int i=0;i<nn;++i){
    43         f[i]=(mx>i ? min(f[(id<<1)-i],mx-i) : 1);
    44         while(i>=f[i] && i+f[i]<nn && ss[i-f[i]]==ss[i+f[i]])  ++f[i];
    45         if(mx<f[i]+i-1)  mx=f[i]+i-1,id=i;
    46         bwl=(bwl+f[i]/2)%dalao;
    47     }
    48     return bwl;
    49 }
    50 ll qckpw(int x,int y){
    51     ll bs=x,bwl=1;
    52     while(y){  if(y&1)  bwl=(bwl*bs)%dalao;  bs=(bs*bs)%dalao;  y>>=1;}
    53     return bwl;
    54 }
    55 int main(){//freopen("ddd.in","r",stdin);
    56     //freopen("ddd.out","w",stdout);
    57     scanf("%s",s);  n=strlen(s),nn=n<<1|1;
    58     for(N=1,L=0;N<n;N<<=1,++L);  N<<=1,++L;
    59     for(int i=0;i<N;++i){
    60         int l=0;
    61         for(int j=i;j;j>>=1)  dig[l++]=j&1;
    62         for(int j=0;j<L;++j)  rvs[i]=(rvs[i]<<1)|dig[j];
    63     }
    64     for(int i=0;i<n;++i)  a[i]=cp(s[i]=='a'),b[i]=cp(s[i]=='b');
    65     for(int i=n;i<N;++i)  a[i]=b[i]=cp(0,0);
    66     fft(a,1),fft(b,1);
    67     for(int i=0;i<N;++i)  a[i]=a[i]*a[i],b[i]=b[i]*b[i];
    68     fft(a,-1),fft(b,-1);
    69     ll ans=0;  int tmp;
    70     for(int i=0;i<N;++i){
    71         tmp=((int)(a[i].r+b[i].r+0.5)+1)/2;
    72         ans=(ans+qckpw(2,tmp)-1)%dalao;
    73     }
    74     ans=(ans+dalao-mnch())%dalao;
    75     cout<<ans<<endl;
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    MySQL之权限管理
    CentOS7使用firewalld打开关闭防火墙与端口
    CentOS 7.2 基于Docker实现MySQL主从架构
    Centos7下安装Docker
    nginx php-fpm安装配置 CentOS编译安装php7.2
    php7的扩展库安装方法
    Android 程序打包及签名
    Message和handler传递对象
    Android AlertDialog去除黑边白边自定义布局(转)
    用MVC做支付宝手机网页支付问题
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6517026.html
Copyright © 2011-2022 走看看