牛客国庆派对day4 导数卷积【NTT】

Link:https://www.nowcoder.com/acm/contest/204/F

 

f^{(i)}(x)的第j项为a[j]*\frac{(n-1-(n-1-j))!}{(n-1-i-(n-1-j))!}

我们设(n-1-j)=p

可以将上述式子化为a[n-1-p]*\frac{(n-1-p)!}{(n-1-i-p)!}

在题中的卷积中构成x^{d}结果的系数的必为:\sum \sum a[n-1-p_{1}]*\frac{(n-1-p_{1})!}{(n-1-i_{1}-p_{1})!} * a[n-1-p_{2}]*\frac{(n-1-p_{2})!}{(n-1-i_{2}-p_{2})!}

其中p_{1}+p_{2}=d,i_{1}=n-1-i_{2}

把上面的用d和n-1代入消去p2和i2,然后换元搞搞就是卷积了

 

代码:

#include<bits/stdc++.h>
#define ll long long
const int N=3e5 + 5;
const ll MOD=998244353;//50000000001507329LL;//998244353 1004535809
using namespace std;
int n,m;
ll a[N],b[N],x[N],y[N];
ll wn[25];
ll Mul(ll x,ll y)//乘法超ll用快速乘,主函数也需要用
{
    ll ans=(x*y-(ll)((long double)x/MOD*y+1e-8)*MOD);
    return ans<0?ans+MOD:ans;
}
ll Qpow(ll a,ll b,ll M)
{
    ll ans=1;a%=M;
    while(b)
    {
        if(b&1) ans=Mul(ans,a);
        a=Mul(a,a);
        b>>=1;
    }
    return ans;
}
void Getwn()//主函数预处理getwn()
{
    for(int i=0;i<25;i++)
    {
        wn[i]=Qpow(3,(MOD-1)/(1<<i),MOD);
    }
}
void NTT(ll *x,int n,int rev)
{
    int i,j,k,ds;
    ll w,u,v;
    for(i=1,j=n>>1,k=n>>1;i<n-1;i++,k=n>>1)
    {
        if(i<j) swap(x[i],x[j]);
        while(j>=k) j-=k,k>>=1;
        if(j<k) j+=k;
    }
    for(i=2,ds=1;i<=n;i<<=1,ds++)
    {
        for(j=0;j<n;j+=i)
        {
            w=1;
            for(k=j;k<j+i/2;k++)
            {
                u=x[k];
                v=Mul(w,x[k+i/2]);
                x[k]=(u+v)%MOD;
                x[k+i/2]=(u-v+MOD)%MOD;
                w=Mul(w,wn[ds]);
            }
        }
    }
    if(rev==-1)
    {
        for(i=1;i<n/2;i++) swap(x[i],x[n-i]);
        w=Qpow(n,MOD-2,MOD);
        for(i=0;i<n;i++) x[i]=Mul(x[i],w);
    }
}

int A[N];
ll fac[N], inv[N];
ll res1[N], res2[N];
void init() {
    fac[0]=1;
    for(int i=1;i<=100000;i++) fac[i] = fac[i-1] * i % MOD;
    inv[100000]=Qpow(fac[100000],MOD-2,MOD);
    for(int i=100000-1;i;i--) inv[i] = inv[i+1] * (i+1) % MOD;
    inv[0]=1;
}
int main()
{
    Getwn();
    init();
    scanf("%d", &n); m=n;
    for(int i=0;i<n;i++)scanf("%d",&A[i]);

    for(int i=0;i<n;i++)a[i]=fac[n-1-i]*A[n-1-i]%MOD;
    for(int i=0;i<n;i++)b[i]=inv[i];
    int len=1,s=n+m;//结果的系数长度
    while(len<s)len<<=1;
    for(int i=n;i<len;i++)a[i]=0;
    for(int i=m;i<len;i++)b[i]=0;//不满二进制数补0
    NTT(a,len,1);NTT(b,len,1);//化成点值表达式
    for(int i=0;i<len;i++)res1[i]=Mul(a[i],a[i]),res2[i]=Mul(b[i],b[i]);
    NTT(res1,len,-1);NTT(res2,len,-1);//还原为多项式
    
    for(int i=0;i<n;i++) res2[i]=res1[n-1-i]*res2[i]%MOD;
    for(int i=0;i<n;i++) {
        printf("%lld", res2[i]);
        if (i==n-1) printf("\n");
        else printf(" ");
    }

}

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值