zoukankan      html  css  js  c++  java
  • 2017 3 11 分治FFT

      

    考试一道题的递推式为$$f[i]=sum_{j=1}^{i} j^k imes (i-1)! imes frac{f[i-j]}{(i-j)!}$$
    这显然是一个卷积的形式,但$f$需要由自己卷过来(我也不知到怎么说),以前只会生成函数的做法,但这题好像做不了(谁教教我怎么做),于是无奈的写了一发暴力,看题解发现是分治FFT.
    分治每层用$f[l]-f[mid]$与$a[1]-a[r-l]$做NTT。
    这样显然每个$f[l]-f[mid]$对$f[mid+1]-f[r]$的贡献都考虑到了。
    因为分治是从1开始的,所以$f[0]$的转移预处理了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define ll long long
     6 #define N 400005
     7 using namespace std;
     8 int n,k;
     9 const int p = 998244353;
    10 ll poow[N],jie[N],ni[N];
    11 ll pw(ll x,ll y)
    12 {
    13     ll lst=1;
    14     while(y)
    15     {
    16         if(y&1)lst=lst*x%p;
    17         x=x*x%p;
    18         y>>=1;
    19     }
    20     return lst;
    21 }
    22 ll f[N];
    23 int R[N],a[N],b[N];
    24 void NTT(int *a,int n,int f,int L)
    25 {
    26     for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
    27     for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
    28     for(int i=1;i<n;i<<=1)
    29     {
    30         int wn=pw(3,((p-1)/(i<<1)*f+p-1)%(p-1));
    31         for(int j=0;j<n;j+=(i<<1))
    32         {
    33             int w=1;
    34             for(int k=0;k<i;k++,w=1LL*w*wn%p)
    35             {
    36                 int x=a[j+k],y=1LL*a[j+k+i]*w%p;
    37                 a[j+k]=(x+y)%p;a[j+k+i]=(x-y+p)%p;
    38             }
    39         }
    40     }
    41     if(f==-1)
    42     {
    43         int nw=pw(n,p-2);
    44         for(int i=0;i<n;i++)a[i]=1LL*a[i]*nw%p;
    45     }
    46     return ;
    47 }
    48 void solve(int l,int r)
    49 {
    50     if(l==r)
    51     {
    52         f[l]=f[l]*jie[l-1]%p;
    53         return ;
    54     }
    55     int mid=(l+r)>>1;
    56     solve(l,mid);int len=r-l+1;int m=len<<1;
    57     for(int i=1;i<len;i++)a[i]=poow[i];
    58     for(int i=l;i<=mid;i++)b[i-l]=f[i]*ni[i]%p;
    59     int L=0;for(len=1;len<m;len<<=1)L++;
    60     for(int i=mid-l+1;i<len;i++)b[i]=0;
    61     NTT(a,len,1,L);NTT(b,len,1,L);
    62     for(int i=0;i<len;i++)a[i]=1LL*a[i]*b[i]%p;
    63     NTT(a,len,-1,L);
    64     for(int i=mid+1;i<=r;i++)f[i]=(f[i]+a[i-l])%p;
    65     solve(mid+1,r);
    66 }
    67 int main()
    68 {
    69     scanf("%d%d",&n,&k);
    70     jie[0]=1;ni[0]=1;
    71     for(int i=1;i<=n;i++)jie[i]=(jie[i-1]*i)%p;
    72     for(int i=1;i<=n;i++)ni[i]=pw(jie[i],p-2);
    73     poow[0]=1;
    74     for(int i=1;i<=n;i++)poow[i]=pw(i,k);
    75     for(int i=1;i<=n;i++)f[i]=poow[i];
    76     solve(1,n);
    77     printf("%lld
    ",f[n]);
    78     return 0;
    79 }
  • 相关阅读:
    想写点啥?
    网站优化记录
    freemarker了解
    spring理解
    mybatis了解
    struts机制
    SSM整合时初始化出现异常
    常用的正则表达式
    MySQL数据库安装配置步骤详解
    完全卸载MySQL数据库,实现重装
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6544713.html
Copyright © 2011-2022 走看看