题意:
分析:
- 前置芝士 : 生成函数 多项式EXP
将题目拆成两问:
-
前缀和
一次前缀和操作 (sum_{j<i}a_j o a_i) 等价于将 (a) 序列的 OGF 乘了一个 (1+x+x^2+x^3dots x^n) 即 (frac{1}{1-x}),(ans=a * frac{1}{(1-x)^k})
-
差分
同理,一次差分操作 (a_i-a_{i-1} o a_{i-1}) 等价于将序列的 OGF 乘了一个 ((1-x)) (ans=a * (1-x)^k)
直接上多项式 EXP
代码:
#include<bits/stdc++.h>
#define inl inline
#define reg register
using namespace std;
namespace zzc
{
typedef long long ll;
const int maxn = 3e5+5;
const long long mod = 1004535809;
inl ll read()
{
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x*10+ch-48)%mod;ch=getchar();}
return x*f;
}
ll n,k,t,l,lim;
ll a[maxn],b[maxn],c[maxn],d[maxn],e[maxn],f[maxn],g[maxn],h[maxn],rev[maxn];
ll qpow(ll x,ll y)
{
ll res=1;
while(y)
{
if(y&1) res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
void ntt(ll *a,ll inv)
{
for(ll i=0;i<lim;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(ll len=1;len<lim;len<<=1)
{
ll w1=qpow(inv==1?3:1004535810/3,(mod-1)/(len<<1));
for(ll i=0;i<lim;i+=(len<<1))
{
ll w=1;
for(ll j=0;j<len;j++)
{
ll x=a[i+j],y=w*a[i+j+len]%mod;
a[i+j]=(x+y)%mod;
a[i+j+len]=(x-y+mod)%mod;
w=w*w1%mod;
}
}
}
if(inv==1) return ;
long long tmp=qpow(lim,mod-2);
for(int i=0;i<lim;i++) a[i]=(a[i]*tmp%mod+mod)%mod;
}
void get_len(int k)
{
lim=1,l=0;
while(lim<(k<<1)) lim<<=1,l++;
for(ll i=0;i<lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
}
void get_inv(ll *f,ll *g,ll k)
{
if(k==1)
{
g[0]=qpow(f[0],mod-2);
return ;
}
get_inv(f,g,(k+1)>>1);
get_len(k);
for(ll i=0;i<k;i++) c[i]=f[i];
for(ll i=k;i<lim;i++) c[i]=0;
ntt(c,1);ntt(g,1);
for(ll i=0;i<lim;i++) g[i]=((2ll-c[i]*g[i]%mod+mod)%mod)*g[i]%mod;
ntt(g,-1);
for(ll i=k;i<lim;i++) g[i]=0;
}
void get_der(ll *f,ll *g,ll k)
{
for(ll i=1;i<k;i++) g[i-1]=i*f[i]%mod;
g[k-1]=0;
}
void get_int(ll *f,ll *g,ll k)
{
for(ll i=1;i<k;i++) g[i]=f[i-1]*qpow(i,mod-2)%mod;
g[0]=0;
}
void get_ln(ll *f,ll *g,ll k)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
get_der(f,a,k);get_inv(f,b,k);get_len(k);
ntt(a,1);ntt(b,1);
for(ll i=0;i<lim;i++) a[i]=a[i]*b[i]%mod;
ntt(a,-1);
get_int(a,g,k);
}
void get_exp(ll *a,ll *b,ll k)
{
if(k==1)
{
b[0]=1;
return ;
}
get_len(k);
get_exp(a,b,(k+1)>>1);get_ln(b,d,k);
for(ll i=0;i<k;i++) e[i]=a[i];
for(ll i=k;i<lim;i++) e[i]=d[i]=0;
ntt(d,1);ntt(e,1);ntt(b,1);
for(ll i=0;i<lim;i++) b[i]=(1-d[i]+e[i]+mod)%mod*b[i]%mod;
ntt(b,-1);
for(ll i=k;i<lim;i++) b[i]=0;
}
void work()
{
n=read();k=read();t=read();
for(int i=0;i<n;i++) f[i]=read();
g[0]=1;g[1]=mod-1;
get_ln(g,h,n);
for(ll i=0;i<n;i++) h[i]=h[i]*k%mod;
memset(g,0,sizeof(g));
get_exp(h,g,n);
if(!t)
{
memset(h,0,sizeof(h));
get_inv(g,h,n);
memcpy(g,h,sizeof(h));
}
get_len(n);
ntt(f,1);ntt(g,1);
for(ll i=0;i<lim;i++) f[i]=f[i]*g[i]%mod;
ntt(f,-1);
for(ll i=0;i<n;i++) printf("%lld ",f[i]);
}
}
int main()
{
zzc::work();
return 0;
}