LINK:一个人的高三楼
求一个数列的K次前缀和。
(nleq 100000,kleq 2^{60})
前缀和K次。这类似于多项式卷积。
构造 普通型生成函数F(x)表示数列中的每一项 0次前缀和(F(x)=sum_{i=0}^{n-1}a_{i+1}x^i)
考虑如何生成1次前缀和 构造多项式G(x).
使得 (F(x)[0] * G(x)=F(x)[1])
可以比较显然的得到(G(x)=sum_{i=0}^{n-1}x^i)
所以所求为(F(x)*(G(x))^k.)
多项式快速幂 复杂度nlognlogk.常数过大过不了。
由于G(x)这个多项式的系数的特殊性 考虑O(1)求出(G(x)^k)的各项系数。
我们只要前n-1项 对于第i项的系数 有K个多项式的某项系数提供 可以写成 (sum_{i=1}{k}w_i=i)
显然是隔板法 系数为C(i+k-1,k-1)=C(i+k-1,i).
直接求不太好求 但是 这些系数是递增的 如C(i+k-1,i),C(i+1+k-1,i+1),C(i+2+k-1,i+2)...
第一项好求为1 第二项可以由第一项推出来。
所以总复杂度 nlogn.
//#include<bitsstdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define put(x) printf("%d
",x)
#define putl(x) printf("%lld
",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE ll i=p;i<=n;++i)
#define go(x) for(ll i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE ll i=n;i>=p;--i)
#define pii pair<ll,ll>
#define mk make_pair
#define mod 998244353
#define RE register
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define ull unsigned long long
#define P 1000000000000000ll
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline ll read()
{
RE ll x=0,f=1;char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const ll MAXN=300010,G=3;
ll n,k,lim;
ll a[MAXN],b[MAXN],rev[MAXN];
ll ksm(ll b,ll p)
{
b=b%mod;ll cnt=1;
while(p)
{
if(p&1)cnt=cnt*b%mod;
b=b*b%mod;p=p>>1;
}
return cnt;
}
inline void NTT(ll *a,ll op)
{
rep(0,lim-1,i)if(rev[i]<i)swap(a[i],a[rev[i]]);
for(ll len=2;len<=lim;len=len<<1)
{
ll mid=len>>1;
ll wn=ksm(G,op==1?(mod-1)/len:mod-1-(mod-1)/len);
for(ll j=0;j<lim;j+=len)
{
ll d=1;
for(ll i=0;i<mid;++i)
{
ll x=a[i+j],y=a[i+j+mid]*d%mod;
a[i+j]=(x+y)%mod;a[i+j+mid]=(x-y+mod)%mod;
d=d*wn%mod;
}
}
}
if(op==-1)
{
ll inv=ksm(lim,mod-2);
rep(0,lim-1,i)a[i]=a[i]*inv%mod;
}
}
signed main()
{
freopen("1.in","r",stdin);
get(n);get(k);b[0]=1;
rep(0,n-1,i)get(a[i]);
if(!k){rep(0,n-1,i)putl(a[i]);return 0;}
rep(1,n-1,i)b[i]=(b[i-1]+b[i-1]*ksm(i,mod-2)%mod*((k-1)%mod)%mod)%mod;
//b[i]=C(i+k-1,i)=C(i+k-2,i-1)+C(i+k-2,i);
lim=1;while(lim<n+n)lim=lim<<1;
rep(1,lim-1,i)rev[i]=rev[i>>1]>>1|((i&1)?lim>>1:0);
NTT(a,1);NTT(b,1);
rep(0,lim-1,i)a[i]=a[i]*b[i]%mod;
NTT(a,-1);
rep(0,n-1,i)putl(a[i]);
return 0;
}
NTT好久没打了 所以调了1h.