• BZOJ3160【万径人踪灭】 【FFT】


    。。恩 打了四五遍 不会也背出来了。。

    BZOJ3160 【听说时限紧?转C++的优势么?】

    上AC代码 fft

     1 /*Problem: 3160
     2     User: cyz666
     3     Language: C++
     4     Result: Accepted
     5     Time:1992 ms
     6     Memory:18492 kb
     7 ****************************************************************/
     8  
     9 #include <bits/stdc++.h>
    10 #define LL long long
    11 const LL mo=1000000007;
    12 const double pi=acos(-1.0);
    13 using namespace std;
    14 struct cp{
    15     double x,y;
    16     cp(double a=0,double b=0):x(a),y(b){}
    17     //cp(double a=0,double b=0){x=a,y=b;}
    18 }a[400005],b[400005],W[200005];
    19 int h[400005],rev[400005],f[200005],c[200005],n,x,m; 
    20 char s; LL ans;
    21 cp operator +(cp a,cp b){
    22     cp c(a.x+b.x,a.y+b.y);
    23     return c;
    24 }
    25 cp operator *(cp a,cp b){
    26     cp c(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
    27     return c;
    28 }
    29 cp operator -(cp a,cp b){
    30     return (cp){a.x-b.x,a.y-b.y};
    31 }
    32 void fft(cp a[],int n,int d=1){
    33     if (d<0) reverse(a+1,a+n);
    34     for (int i=0;i<n;++i)
    35         if (i<rev[i]) swap(a[i],a[rev[i]]);
    36     for (int i=0;i<n/2;++i)
    37         W[i]=cp(cos(2*pi/n*i),sin(2*pi/n*i));
    38     for (int m=2,k=1;m<=n;k=m,m<<=1)
    39         for (int i=0;i<n;i+=m)
    40         for (int j=i;j<i+k;++j){
    41             cp u=a[j],v=a[j+k]*W[n/m*(j-i)];
    42             a[j]=u+v,a[j+k]=u-v;
    43         }
    44     if (d<0) for (int i=0;i<n;++i) a[i].x/=n;
    45 }
    46 int main(){
    47     while (scanf("%c",&s)&&isalpha(s))
    48         s=='a'?c[++++n]=1:c[++++n]=2;
    49     c[0]=-1; c[n+2]=-2;
    50     for (int i=1;i<=n;++i){
    51         if (x+f[x]>i) f[i]=min(f[x+x-i],x+f[x]-i);
    52         while (c[i+f[i]]==c[i-f[i]]) ++f[i]; --f[i];
    53         if (i+f[i]>x+f[x]) x=i;
    54         ans+=f[i]/2; if (ans>=mo) ans-=mo;
    55     }
    56     m=ceil((log(n)/log(2))); m=1<<m;
    57     for (int i=1;i<m;++i)rev[i]=(rev[i>>1]>>1)+(m>>1)*(i&1);
    58     x=0; for (int i=2;i<=n;++++i) c[++x]=c[i]; n=x;
    59     for (int i=1;i<=n;++i) c[i]==1?a[i].x=1:b[i].x=1;
    60     fft(a,m);  fft(b,m);
    61     for (int i=0;i<m;++i) a[i]=a[i]*a[i],b[i]=b[i]*b[i];
    62     fft(a,m,-1); fft(b,m,-1);
    63     h[0]=1; for (int i=1;i<=n;++i)h[i]=(h[i-1]+h[i-1])%mo;
    64     int x;  ans=mo-ans; 
    65     for (int i=1;i<n+n;++i){
    66         x=round(a[i].x+b[i].x); 
    67         ans+=h[x+1>>1]-1; if (ans>=mo) ans-=mo;
    68     }
    69     ans=(ans-n+1+mo)%mo;
    70     printf("%lld",ans);
    71     return 0;
    72 }
    KriTo

      

    然后 顺手写了个ntt板子扔这(没用题目测过对不对)

    mo的原根g的定义:g^1,g^2,...,g^(mo-1) 在%mo意义下各不相同。

     1 #include <bits/stdc++.h>
     2 #define LL long long
     3 using namespace std;
     4 int g1,g2,N,n,k,x,W[1050000],a[1050000],b[1050000],rev[1050000],mo1,mo2;
     5 LL po(LL x,LL y,LL mo){
     6     LL z=1; if (y<0) y=y%(mo-1)+mo-1;
     7     for (;y;y>>=1,x=x*x%mo)
     8     if (y&1) z=z*x%mo;
     9     return z;
    10 }
    11 int getg(LL mo){
    12     LL y=mo-1,x=floor(sqrt(y)); int fl; 
    13     for (int g=2;;++g){
    14         fl=1;
    15         for (int i=2;i<=x;++i) if (!(y%i))
    16         if (po(g,i,mo)==1||po(g,y/i,mo)==1) {fl=0;break;}
    17         if (fl) return g;
    18     }
    19 }
    20 void ntt(int a[],int n,int d,int mo,int G){    //n整除(mo-1)
    21     if (d<0) reverse(a+1,a+n);
    22     for (int i=0;i<n;++i)
    23         if (i<rev[i]) swap(a[i],a[rev[i]]);
    24     W[0]=1; LL X=po(G,(mo-1)/n,mo);
    25     for (int i=1;i<n/2;++i) W[i]=X*W[i-1]%mo;
    26     for (int m=2,k=1;m<=n;k=m,m<<=1)
    27         for (int i=0;i<n;i+=m)
    28         for (int j=i;j<i+k;++j){
    29             int u=a[j],v=1ll*a[j+k]*W[n/m*(j-i)]%mo;
    30             a[j]=u+v>=mo?u+v-mo:u+v;
    31             a[j+k]=u-v<0?u-v+mo:u-v;
    32         }
    33     if (d<0){
    34         X=po(n,mo-2,mo);
    35         for (int i=0;i<n;++i) a[i]=X*a[i]%mo;
    36     }
    37 }
    38 int main(){
    39     mo1=998244353; mo2=1004535809;
    40     g1=getg(mo1); g2=getg(mo2);
    41     scanf("%d%d",&n,&k); W[0]=1;
    42     for (int i=1;i<=n;++i)
    43         scanf("%d",&x),a[x]=1,b[x]=1;
    44     N=1048576;
    45     for (int i=0;i<N;++i) rev[i]=rev[i>>1]>>1|(i&1?N>>1:0);
    46     ntt(a,N,1,mo1,g1); ntt(b,N,1,mo2,g2);
    47     for (int i=0;i<N;++i)
    48         a[i]=po(a[i],k,mo1),b[i]=po(b[i],k,mo2);
    49     ntt(a,N,-1,mo1,g1); ntt(b,N,-1,mo2,g2);
    50     for (int i=0;i<N;++i){
    51         if (a[i]<0) a[i]+=mo1;
    52         if (b[i]<0) b[i]+=mo2;
    53     }
    54     for (int i=0;i<N;++i) if (a[i]||b[i]) printf("%d ",i); puts("");
    55     return 0;
    56 }
    AsuNa

    若多项式相乘的最高次为n, 则FFT,NTT的数组大小要开到>n的最小的2的幂。 即 1<<(int)ceil(log(n+1)/log(2))

    给几个模数:

    1004535809=479*2^21+1,   原根=3

    998244353=7*17*2^23+1 ,原根=3

    469762049=7*2^26+1      ,原根=3

    转载请标明出处 http://www.cnblogs.com/cyz666/
  • 相关阅读:
    k3d安装k3s
    python自动目录环境
    http状态码
    linux下切换jdk版本
    pycharm py代码默认模板设置
    kubectl命令
    国内安装k3s
    minikube安装
    hmac-md5
    abstract class 与 interface
  • 原文地址:https://www.cnblogs.com/cyz666/p/6382844.html
Copyright © 2020-2023  润新知