• 【BZOJ 3160】 3160: 万径人踪灭 (FFT)


    3160: 万径人踪灭

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 1440  Solved: 799

    Description

    Input

    Output

    Sample Input

    Sample Output

    HINT

    Source

    【分析】

      看题目被吓死,其实很多废话。。

      还是自己想出来了。。FFT好强啊。。可以加速很多东西的说。

      然后就是,枚举对称轴吧?

      假设a[i]==a[j],那么用i+j表示它的对称轴。

      共有0~2*n的对称轴,对于每个对称轴它的对称点对个数就是$F[k]=sum s[k-i]==s[k+i]$

      注意到只有a和b,假设只考虑a相同,令$a[i]=s[i]=='a'?1:0$

      那么就是$F[k]=sum a[k-i]*a[k+i]$

      化成卷积形式,可以用FFT做了。用b也做一遍

      最后答案是$sum 2^{F[k]}$-空串-回文子串(不能连续嘛)

      回文子串我用马拉车打了,,,然后打错了,,,然后TLE了,,,以为是FFT的递归版太慢,还去学了迭代打法【醉生梦死。。。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 #define Maxn 100010*8
     9 #define Mod 1000000007
    10 #define LL long long
    11 const double pi=acos(-1);
    12 
    13 int mymin(int x,int y) {return x<y?x:y;}
    14 
    15 struct P
    16 {
    17     double x,y;
    18     P() {x=y=0;}
    19     P(double x,double y):x(x),y(y){}
    20     friend P operator + (P x,P y) {return P(x.x+y.x,x.y+y.y);}
    21     friend P operator - (P x,P y) {return P(x.x-y.x,x.y-y.y);}
    22     friend P operator * (P x,P y) {return P(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);}
    23 }a[Maxn];
    24 int i,j,k;
    25 
    26 int nn=1,R[Maxn];
    27 void fft(P *a,int f)
    28 {
    29     for(i=0;i<nn;i++) if(i<R[i]) swap(a[i],a[R[i]]);
    30     for(i=1;i<nn;i<<=1)
    31     {
    32         P wn(cos(pi/i),f*sin(pi/i));
    33         for(int ad=i<<1,j=0;j<nn;j+=ad)
    34         {
    35             P w(1,0);
    36             for(k=0;k<i;k++,w=w*wn)
    37             {
    38                 P x=a[j+k],y=w*a[j+k+i];
    39                 a[j+k]=x+y;a[j+k+i]=x-y;
    40             }
    41         }
    42     }
    43 }
    44 
    45 char s[Maxn];
    46 int ans[Maxn];
    47 
    48 int aa[Maxn],pp[Maxn];
    49 int get_manacher(int ll)
    50 {
    51     int mx=0,id=0;
    52     for(int i=1;i<=ll;i++)
    53     {
    54         int k;
    55         if(i<mx) k=mymin(pp[2*id-i],mx-i+1);
    56         else k=1;
    57         while(aa[i+k]==aa[i-k]&&i-k>=1&&i+k<=ll) k++;
    58         pp[i]=k;
    59         if(i+pp[i]-1>mx) mx=i+pp[i]-1,id=i;
    60     }
    61     int as=0;
    62     for(int i=1;i<=ll;i+=2) as=(as+(pp[i]+1)/2)%Mod;
    63     for(int i=2;i<=ll;i+=2) as=(as+pp[i]/2)%Mod;
    64     return as;
    65 }
    66 
    67 int bin[Maxn];
    68 
    69 int main()
    70 {
    71     scanf("%s",s);
    72     int n=strlen(s);n--;
    73     for(i=0;i<=n;i++) a[i].x=(s[i]=='a'?1:0);
    74     
    75     int ll=0;nn=1;
    76     while(nn<=n+n) ll++,nn<<=1;
    77     for(i=0;i<nn;i++) R[i]=(R[i>>1]>>1)|((i&1)<<(ll-1));
    78     
    79     fft(a,1);for(i=0;i<=nn;i++) a[i]=a[i]*a[i];fft(a,-1);
    80     for(i=0;i<=n+n;i++) ans[i]=(int)(a[i].x/nn+0.5);
    81     
    82     for(i=0;i<=nn;i++) a[i].x=a[i].y=0;
    83     for(i=0;i<=n;i++) a[i].x=(s[i]=='a'?0:1),a[i].y=0;
    84     
    85     fft(a,1);for(i=0;i<=nn;i++) a[i]=a[i]*a[i];fft(a,-1);
    86     for(i=0;i<=n+n;i++) ans[i]+=(int)(a[i].x/nn+0.5);
    87     
    88     for(i=0;i<=n+n;i++) ans[i]=(ans[i]+1)/2;
    89     int a1=0;
    90     bin[0]=1;for(i=1;i<=n;i++) bin[i]=(bin[i-1]*2)%Mod;
    91     for(i=0;i<=n+n;i++) a1=(a1+bin[ans[i]])%Mod;
    92     a1-=n+n+1;
    93     aa[0]=3;for(int i=0;i<=n;i++) aa[2*i+1]=s[i]-'a',aa[2*i+2]=2;aa[2*n+2]=5;
    94     a1-=get_manacher(2*n+1);
    95     a1=(a1%Mod+Mod)%Mod;
    96     printf("%d
    ",a1);
    97     return 0;
    98 }
    View Code

    【所以我现在会迭代打法了hhh

    2017-04-13 18:42:35

  • 相关阅读:
    timeouts _ golang
    select.go
    channel directions _ golang
    channel synchronization _ golang
    channel _ buffering
    servlet:共享资源造成的线程冲突
    java:多线程的 共享资源冲突问题
    jsp:通过过滤器进行网页的资源管理
    jsp:通过Session控制登陆时间和内部页面的访问
    java:数据结构
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6705463.html
Copyright © 2020-2023  润新知