zoukankan      html  css  js  c++  java
  • FFT的常数优化

    卡得一手好常数。。学习了。。(似乎只对FFT有效)

    JZOJ 4349

     1 #include <bits/stdc++.h>
     2 #define LL long long
     3 #define DB long double
     4 using namespace std;
     5 const int mo=100003;
     6 const DB pi=acos(-1);
     7 int K,T,p[360005],q[360005],f[70005],n,m,k,a[70005],rev[70005],ans;
     8 DB COS[70005],SIN[70005],Cos[70005],Sin[70005];
     9 struct cp{
    10     DB x,y;
    11     cp (DB p=0,DB q=0){x=p,y=q;}
    12 }w[70005],N[35005];
    13 cp operator+(cp a,cp b){
    14     return cp(a.x+b.x,a.y+b.y);
    15 }
    16 cp operator-(cp a,cp b){
    17     return cp(a.x-b.x,a.y-b.y);
    18 }
    19 cp operator*(cp a,cp b){
    20     return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
    21 }
    22 LL po(LL x,int y){
    23     LL z=1;
    24     for (;y;y>>=1,x=x*x%mo)
    25     if (y&1) z=z*x%mo;
    26     return z;
    27 }
    28 LL C(int n,int m){
    29     return n<m?0:(n<mo?1ll*p[n]*q[m]%mo*q[n-m]%mo:C(n%mo,m%mo)*C(n/mo,m/mo)%mo);
    30 }
    31 void fft(cp a[],int n,int d=1){
    32     for (int i=0;i<n;++i) if (i<rev[i]) swap(a[i],a[rev[i]]);
    33     for (int m=2,k=1;m<=n;k=m,m<<=1){
    34         cp wn;
    35         wn=d>0?cp(COS[m],SIN[m]):cp(Cos[m],Sin[m]);
    36         N[0]=cp(1,0);
    37         for (int i=1;i<k;++i) N[i]=N[i-1]*wn;
    38         for (int i=0;i<n;i+=m)
    39         for (int j=i;j<i+k;++j){
    40             cp u=a[j],v=a[j+k]*N[j-i];
    41             a[j]=u+v; a[j+k]=u-v;
    42         }
    43     }
    44     if (d==-1) for (int i=0;i<=n;++i) a[i].x/=n;
    45 }
    46 void preF(){
    47     f[1]=9; f[2]=243; f[3]=16224;
    48     int t=12,X=299,Y=1<<t;
    49     for (int i=4;i<=60000;++i){
    50         int x=1,y=0;
    51         for (int j=0;j<=4;++j,x*=3)
    52             (f[i]+=(C(4,j)*x*(Y-X+y)%mo))%=mo,(y+=C(t,i-j-1))%=mo;
    53         f[i]=(f[i]%mo+mo)%mo;
    54         for (int j=1;j<=6;++j)
    55             X=(X*2-C(t,i-1))%mo,++t;
    56         X=(X+C(t,i))%mo; Y=Y*64%mo;
    57     }
    58 }
    59 int main(){
    60     for (int i=2;i<=65536;i<<=1)
    61         COS[i]=cos(pi*2/i),Cos[i]=cos(pi*-2/i),
    62         SIN[i]=sin(pi*2/i),Sin[i]=sin(pi*-2/i);
    63     scanf("%d",&T);
    64     p[0]=q[0]=1;
    65     for (int i=1,x;i<mo;++i){
    66         for (x=i;x%mo==0;x/=mo);
    67         p[i]=1ll*p[i-1]*x%mo;
    68     }
    69     q[mo-1]=po(p[mo-1],mo-2);
    70     for (int i=mo-2,x;i;--i){
    71         for (x=i+1;x%mo==0;x/=mo);
    72         q[i]=1ll*q[i+1]*x%mo;
    73     }
    74     preF();
    75     while (T--){
    76         scanf("%d%d",&n,&K);
    77         for (int i=1;i<=n;++i) a[i]=f[i];
    78         for (m=1;m<n;m<<=1);
    79         for (int i=n+1;i<=m;++i) a[i]=0; n=m;
    80         for (m=2,k=1;m<=n;k=m,m<<=1){
    81             for (int i=0;i<m;++i) rev[i]=rev[i>>1]>>1|(i&1)*(m>>1);
    82             for (int i=1;i<=n;i+=m){
    83                 w[0]=cp(2,0);
    84                 for (int j=i;j<i+k;++j) w[j-i+1]=cp(a[j]+a[j+k],a[j]-a[j+k]);
    85                 for (int j=k+1;j<m;++j) w[j]=cp(0,0);
    86                 fft(w,m);
    87                 for (int j=0;j<m;++j) w[j]=w[j]*w[j];
    88                 fft(w,m,-1);
    89                 for (int j=i;j<i+m-1;++j) a[j]=(LL)round(w[j-i+1].x/4)%mo;
    90                 a[i+m-1]=(LL)round(w[0].x/4-1)%mo;
    91             }
    92         }
    93         ans=0;
    94         for (int i=K;i<=n;++i) (ans+=a[i])%=mo;
    95         printf("%d
    ",(ans%mo+mo)%mo);
    96     }
    97     return 0;
    98 }
    DAISHI
  • 相关阅读:
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言I博客作业03
    C语言I博客作业02
    作业01
    java ui 点点记
    eclipse修改workspace目录
    postgres恢复
    JDK1.4和JDK1.5以及1.6
  • 原文地址:https://www.cnblogs.com/cyz666/p/8227694.html
Copyright © 2011-2022 走看看