• hdu-6900


    思路来源:penguin 学长

    传送门


    【题面大意】

    给定多项式 (displaystyle f_1(x)=sum_{i=0}^na_ix^i) 与序列 ({b_n},{c_n}) 。已知递推式 (f_n=b_nf_{n-1}'+c_nf_{n-1}(n>1)) ,求 (f_n)


    【分析】

    展开几项得到:

    ( herefore f_n=b_nf_{n-1}'+c_nf_{n-1})
    (qquad =b_n(b_{n-1}f'_{n-2}+c_{n-1}f_{n-2})'+c_n(b_{n-1}f'_{n-2}+c_{n-1}f_{n-2}))
    (qquad =b_nb_{n-1}f^{(2)}_{n-2}+(b_nc_{n-1}+b_{n-1}c_n)f^{(1)}_{n-2}+c_nc_{n-1}f^{(0)}_{n-2})
    (qquad =b_nb_{n-1}b_{n-2}f^{(3)}_{n-3}+(b_nb_{n-1}c_{n-2}+b_nc_{n-1}b_{n-2}+c_nb_{n-1}b_{n-2})f^{(2)}_{n-3}+(b_nc_{n-1}c_{n-2}+c_nb_{n-1}c_{n-2}+c_nc_{n-1}b_{n-2})f^{(1)}_{n-3}+c_nc_{n-1}c_{n-2}f^{(0)}_{n-3})

    观察式子可得,系数最终与 (displaystyle prod_{i=2}^n(c_ix+b_i)) 相同。

    可证明确实相同

    (displaystyle D(x)=prod_{i=2}^n(c_ix+b_i)=sum_{i=0}^{n-1}d_ix^i)

    ( herefore displaystyle f_n=d_0f_1^{(n-1)}+d_1f_1^{(n-2)}+d_2f_1^{(n-3)}+cdots d_{n-1}f_1^{(0)}=sum_{i=0}^{n-1}d_{n-1-i}f_1^{(i)})

    ( herefore displaystyle f_n[m]=sum_{i=0}^{n-1}d_{n-1-i}f_1^{(i)}[m])

    考虑 (f^{(i)}[m]=f_1^{(i-1)}[m+1]cdot (m+1)=cdots =f_1[m+i]cdot {(m+i)!over m!})

    故代入移项得 (displaystyle m!cdot f_n[m]=sum_{i=0}^{n-1}d_{n-1-i}cdot (m+i)!cdot f_1[m+i])

    (e_i=i!cdot f_1[i])

    (displaystyle m!cdot f_n[m]=sum_{i=0}^{n-1}d_{n-1-i}e_{m+i}=(Dcdot E)[n-1+m])

    因此最后可以卷积求得,复杂度为 (O(nlog n))

    而前面的 (D(x)) ,可以考虑分治求解:

    设前 ({nover 2}) 项合并,后 ({nover 2}) 项合并,此时合并这两项,复杂度为 (O(nlog n))

    而前后两项的合并可以递归处理,故根据主定理 (T(n)=2T({nover 2})+O(nlog n)) ,可以解得复杂度为 (O(nlog^2 n))


    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN=2e6+10,MOD=998244353,inv3=(MOD+1)/3,Lim=1<<21;
    int N,F[Lim],D[20][2][Lim],E[Lim],Frac[MAXN],InF[MAXN],C[MAXN],B[MAXN],POmega[22],NOmega[22];
    inline int fpow(int a,int x) { int ans=1; for(;x;x>>=1,a=1ll*a*a%MOD) if(x&1) ans=1ll*ans*a%MOD; return ans; }
    inline int inv(int a) { return fpow(a,MOD-2); }
    inline void pre(){
        Frac[0]=1;
        for(register int i=1;i<=2e6;++i) Frac[i]=1ll*Frac[i-1]*i%MOD;
        InF[2000000]=inv(Frac[2000000]);
        for(register int i=2e6;i>=1;--i) InF[i-1]=1ll*InF[i]*i%MOD;
    
        POmega[21]=fpow(3,MOD>>21);
        for(register int i=20;i>=0;--i) POmega[i]=1ll*POmega[i+1]*POmega[i+1]%MOD;
        NOmega[21]=fpow(inv3,MOD>>21);
        for(register int i=20;i>=0;--i) NOmega[i]=1ll*NOmega[i+1]*NOmega[i+1]%MOD;
    }
    inline int add(int a,int b) { return (a+b>=MOD)?(a+b-MOD):(a+b); }
    inline int dis(int a,int b) { return (a-b<0)?(a-b+MOD):(a-b); }
    int L,Rev[Lim],invL;
    inline void preNTT(){
        Rev[1]=L>>1;
        for(register int i=2;i<L;++i) Rev[i]=(Rev[i>>1]>>1)|Rev[i&1];
        invL=inv(L);
    }
    inline void NTT(int f[Lim],int Omega[22],int op){
        for(register int i=1;i<L;++i) if(i<Rev[i]) swap(f[i],f[Rev[i]]);
        for(register int bas=2,mid=1,lb=1;bas<=L;bas<<=1,mid<<=1,++lb)
            for(register int l=0,omega=Omega[lb],buf;buf=1,l<L;l+=bas)
                for(register int k=l,tmp;tmp=1ll*buf*f[k+mid]%MOD,k<mid+l;++k,buf=1ll*buf*omega%MOD)
                    f[k+mid]=dis(f[k],tmp),f[k]=add(f[k],tmp);
        if(op==-1){
            for(register int i=0;i<L;++i) f[i]=1ll*invL*f[i]%MOD;
        }
    }
    inline void mul(int f[Lim],int g[Lim],int h[Lim],int N,int M){
        static int p[Lim],q[Lim];
        L=1;
        while(L<N+M+1) L<<=1;
        preNTT();
        for(register int i=0;i<L;++i) p[i]=q[i]=0;
        for(register int i=0;i<=N;++i) p[i]=f[i];
        for(register int i=0;i<=M;++i) q[i]=g[i];
        NTT(p,POmega,1);
        NTT(q,POmega,1);
        for(register int i=0;i<L;++i) h[i]=1ll*p[i]*q[i]%MOD;
        NTT(h,NOmega,-1);
    }
    void mergePoly(int Head,int Tail,int Dep,int isLeft,int Len){
        if(Head==Tail){
            D[Dep][isLeft][1]=C[Head];
            D[Dep][isLeft][0]=B[Head];
            return ;
        }
        mergePoly(Head,Head+Tail>>1,Dep+1,0,Len+1>>1);
        mergePoly(Head+Tail+2>>1,Tail,Dep+1,1,Len+1>>1);
        mul(D[Dep+1][0],D[Dep+1][1],D[Dep][isLeft],Len+1>>1,Len+1>>1);
        for(register int i=0;i<L;++i) D[Dep+1][0][i]=D[Dep+1][1][i]=0;
    }
    inline void work(){
        cin>>N;
        for(register int i=0;i<=N;++i) cin>>E[i],E[i]=1ll*E[i]*Frac[i]%MOD;
        for(register int i=2;i<=N;++i) cin>>B[i];
        for(register int i=2;i<=N;++i) cin>>C[i];
        mergePoly(2,N,1,0,N-1);
        mul(D[1][0],E,F,N,N);
        cout<<F[N-1];
        for(register int i=1;i<=N;++i) cout<<' '<<1ll*F[i+N-1]*InF[i]%MOD;
        for(register int i=0;i<L;++i) E[i]=B[i]=C[i]=F[i]=D[1][0][i]=0;
        cout<<'
    ';
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        pre();
        int T;
        cin>>T;
        while(T--) work();
        cout.flush();
        return 0;
    }
    
  • 相关阅读:
    【Node】fs
    ☀【滚动条】动画,固定
    洛谷——P3817 小A的糖果
    洛谷——P1316 丢瓶盖
    洛谷—— P1190 接水问题
    CODEVS——T1332 上白泽慧音 || 洛谷——P1726 上白泽慧音
    CODEVS——T3008 加工生产调度
    python(20)- 列表生成式和生成器表达式练习Ⅱ
    MTK Android 编译命令
    第六届深圳国际物联网和智慧中国博览会(2014)总结
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/13705300.html
Copyright © 2020-2023  润新知