• 解题:洛谷4721 [模板]分治FFT


    题面

    这是CDQ入门题,不要被题目名骗了,这核心根本不在不在FFT上啊=。=

    因为后面的项的计算依赖于前面的项,不能直接FFT。所以用CDQ的思想,算出前面然后考虑给后面的贡献

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=100005,mod=998244353;
     6 int a[4*N],b[4*N],rev[4*N],f[N],g[N],n,G,Gi;
     7 void exGCD(int a,int b,int &x,int &y)
     8 {
     9     if(!b) {x=1,y=0; return ;}
    10     exGCD(b,a%b,y,x),y-=a/b*x;
    11 }
    12 int Qpow(int x,int k)
    13 {
    14     if(k==1) return x;
    15     int tmp=Qpow(x,k/2);
    16     return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
    17 }
    18 int Inv(int x,int m)
    19 {
    20     int xx,yy;
    21     exGCD(x,m,xx,yy);
    22     return (xx%m+m)%m;
    23 }
    24 void NTT(int *arr,int len,int typ)
    25 {
    26     for(int i=0;i<=len;i++)
    27         if(rev[i]>i) swap(arr[rev[i]],arr[i]);
    28     for(int i=2;i<=len;i<<=1)
    29     {
    30         int lth=i>>1,ort=Qpow(~typ?G:Gi,(mod-1)/i);
    31         for(int j=0;j<len;j+=i)
    32         {
    33             int ori=1,tmp;
    34             for(int k=j;k<j+lth;k++,ori=1ll*ori*ort%mod)
    35             {
    36                 tmp=1ll*ori*arr[k+lth]%mod;
    37                 arr[k+lth]=(arr[k]-tmp+mod)%mod;
    38                 arr[k]=(arr[k]+tmp)%mod;
    39             }
    40         }
    41     }
    42     if(typ==-1)
    43         for(int i=0,ni=Inv(len,mod);i<len;i++) 
    44             arr[i]=1ll*arr[i]*ni%mod;
    45 }
    46 void CDQ(int l,int r,int mid)
    47 {
    48     int len=r-l+1,m=1;
    49     for(int i=l;i<=mid;i++) a[i-l]=f[i];
    50     for(int i=0;i<len;i++) b[i]=g[i]; len+=mid-l+1;
    51     while(m<=len) m<<=1;
    52     for(int i=1;i<=m;i++) rev[i]=(rev[i>>1]>>1)+(i&1)*(m>>1);
    53     NTT(a,m,1),NTT(b,m,1);
    54     for(int i=0;i<=m;i++) a[i]=1ll*a[i]*b[i]%mod;
    55     NTT(a,m,-1);
    56     for(int i=mid+1;i<=r;i++) f[i]+=a[i-l],f[i]%=mod;
    57     for(int i=0;i<=m;i++) a[i]=b[i]=0;
    58 }
    59 void Divide(int l,int r)
    60 {
    61     if(l==r) return;
    62     int mid=(l+r)/2;
    63     Divide(l,mid),CDQ(l,r,mid),Divide(mid+1,r);
    64 }
    65 int main()
    66 {
    67     scanf("%d",&n);
    68     for(int i=1;i<n;i++) scanf("%d",&g[i]);
    69     f[0]=1,G=3,Gi=Inv(G,mod),Divide(0,n-1);
    70     for(int i=0;i<n;i++) printf("%d ",f[i]);
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    HTML5 Input 类型
    Html5 web 储存
    解决json日期格式问题的3种方法(转载)
    Json格式串处理
    全局图片防盗链处理
    我的博客开张了
    iPhone手机屏幕分辨率
    通过CSS3伪类,美化Radio按钮样式
    测试用例 相关
    MongoDB基本命令
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10222165.html
Copyright © 2020-2023  润新知