一个人的高三楼

题目链接:Click here

Solution:

题目名字有点伤感啊。。。

直接看题吧,\(k\)次前缀和,瞬间想到\(O(nk)\)的做法,20pts到手了,走吧!

回到正题。。。不难想到,我们构造一个生成函数\(G(x)=\sum_{i=0}^n x^i\),同时有\(A(x)=\sum_{i=1}^n a_ix^i\)

那么\(A\times G\)就相当于对\(A\)做了一次前缀和了,那么\(S_n^k=A\times G^k\),难道要多项式快速幂?

多项式快速幂是不可能的,这辈子都不可能的,考虑\(G\)的特殊性,它的每一项系数都是1

我们一下子就能发现,\(G^k\)与组合数的关系,\(G^k\)的第\(i\)项的系数就是\({i+k-1\choose k-1}\),不就是插板法吗

那么我们把\(G^k\)求出来之后,直接上\(NTT\)即可

Code:

#include<bits/stdc++.h>
#define int long long 
#define Pi acos(-1.0)
using namespace std;
const int N=4e5+11;
const int mod=998244353;
int n,m,k,len=1,tim,p[N];
int a[N],trans[N],inv[N];
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int qpow(int u,int t){
    int re=1;
    while(t){
        if(t&1) re=re*u%mod;
        t>>=1;u=u*u%mod;
    }return re;
}
void NTT(int *v,int flag){
    for(int i=0;i<len;i++)
        if(i<p[i]) swap(v[i],v[p[i]]);
    for(int l=2;l<=len;l<<=1){
        int wn=qpow(3,(mod-1)/l);
        if(flag==-1) wn=qpow(wn,mod-2);
        for(int st=0;st<len;st+=l){
            int w=1;
            for(int u=st;u<st+(l>>1);u++,w=w*wn%mod){
                int x=v[u],y=w*v[u+(l>>1)]%mod;
                v[u]=(x+y)%mod;v[u+(l>>1)]=(x-y+mod)%mod;
            }    
        }
    }
}
signed main(){
    n=m=read();k=read()%mod;++n;++m;
    for(int i=1;i<n;i++) a[i]=read();
    while(len<=max(n,m)*2) len=len<<1,++tim;
    for(int i=0;i<len;i++)
        p[i]=(p[i>>1]>>1)|((i&1)<<(tim-1));
    trans[0]=1;inv[1]=1;
    for(int i=2;i<=len;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    for(int i=1;i<m;i++,k=(k+1)%mod) trans[i]=trans[i-1]*k%mod*inv[i]%mod;
    NTT(a,1);NTT(trans,1);
    for(int i=0;i<len;i++) a[i]=a[i]*trans[i]%mod;
    NTT(a,-1);for(int i=0;i<=len;i++) a[i]=a[i]*inv[len]%mod;
    for(int i=1;i<n;i++) printf("%lld\n",a[i]);
    return 0;
}

posted @ 2020-01-28 23:18  DQY_dqy  阅读(111)  评论(0编辑  收藏  举报