P5488-差分与前缀和【NTT,生成函数】

1|0正题

题目链接:https://www.luogu.com.cn/problem/P5488


1|1题目大意

求一个长度为n的序列的k阶差分/前缀和。


1|2解题思路

先考虑前缀和怎么做
搞出来生成函数就是

(i=0naixi)(i=0xi)k

然后根据常识我们知道(i=0xi)k=i=0(i+k1i)xi,当然也可以理解为xi的系数就是每次会往后跳任意格(可以是0),然后k次跳i步的方案数。

之后式子

(i=0naixi)(i=0(i+k1i)xi)

直接卷就好了

然后是差分,就是

i=0naixi(i=0xi)k

直接上多项式除法就好 。考虑怎么转换这个式子,我们需要用生成函数的方法了,上等比数列公式就有(i=0xi)k=1(1x)k

那么它的倒数就是(1x)k,上二项式定理就有i=0k(1)i(ki)xi

然后也是两个式子卷起来就好了。

然后k可以直接模p,考虑f(k)=(i=0xi)k那么有f(kn)=f(k)n所以直接让kp即可

时间复杂度O(nlogn)


1|3code

#include<cstdio> #include<algorithm> #include<cstring> #define ll long long using namespace std; const ll N=(1e5)*6,P=1004535809,g=3; struct poly{ ll a[N],n; }G,F; ll n,k,t,inv[N],r[N]; char s[N]; ll power(ll x,ll b){ ll ans=1; while(b){ if(b&1)ans=ans*x%P; x=x*x%P;b>>=1; } return ans; } void NTT(ll *f,ll op,ll n){ for(ll i=0;i<n;i++) if(r[i]<i)swap(f[i],f[r[i]]); for(ll p=2;p<=n;p<<=1){ ll len=(p>>1); ll tmp=power(g,(P-1)/p); if(op)tmp=power(tmp,P-2); for(ll k=0;k<n;k+=p){ ll buf=1; for(ll i=k;i<k+len;i++){ ll tt=buf*f[i+len]%P; f[i+len]=(f[i]-tt+P)%P; f[i]=(f[i]+tt)%P; buf=buf*tmp%P; } } } if(op){ int invn=power(n,P-2); for(int i=0;i<n;i++) f[i]=f[i]*invn%P; } return; } void mul(poly &a,poly &b){ ll n=1; while(n<=a.n+b.n)n<<=1; for(ll i=0;i<n;i++) r[i]=(r[i>>1]>>1)^((i&1)?(n>>1):0); NTT(a.a,0,n);NTT(b.a,0,n); for(ll i=0;i<n;i++) a.a[i]=a.a[i]*b.a[i]%P; NTT(a.a,1,n); return; } int main() { scanf("%lld",&n); scanf("%s",s);ll l=strlen(s); scanf("%lld",&t); for(ll i=0;i<l;i++) k=(k*10+s[i]-'0')%P; inv[1]=1; for(ll i=2;i<=n;i++) inv[i]=(P-(P/i)*inv[P%i]%P)%P; for(ll i=0;i<n;i++) scanf("%lld",&F.a[i]); G.a[0]=1; for(ll i=1;i<=n;i++){ if(!t)G.a[i]=G.a[i-1]*(i+k-1)%P*inv[i]%P; else{ if(i>k)break; G.a[i]=(-1)*G.a[i-1]*(k-i+1)%P*inv[i]%P; G.a[i]=(G.a[i]+P)%P; } } G.n=F.n=n; mul(G,F); for(ll i=0;i<n;i++) printf("%lld ",G.a[i]); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/14234864.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(146)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示