CCPC2021 广州A/CF Gym103415A
Description
给定 和长度为 的序列 ,求
的值模 的结果
Solution
写出 大概可以把答案写成下式并进行一定程度的和式变换
最后一步使用了数列 ( 为常数)的 为 ,证明考虑对常数 归纳,使用了最基础的组合数求一行的和
将 看做自变量,剩下的看成多项式可以分治乘法求出多项式本身,但是别扭的是这个 ,不过对于每个 都会配凑一个 , 个式子累乘起来那么对于 的项必然跟着一个 ,找指数时对着等号最前面的 的 减就行了
分治乘法的叶子处需要快速求第二类斯特林数一行,由于 的上界是可以接受的,那么逐个快速求就行了
剩下的工作是统计答案,考虑 对某个 的贡献系数:现将 减掉 ,
直接对着 求一列和就能得到 ,即 对答案的贡献
组合数推一下就行了,不要直接算
写题解的初衷是看网上没有题解,所以希望能给有需要的人一些帮助吧
Code
inline poly Mul(poly a,poly b){
int n=a.size(),m=b.size(),lim=1;
while(lim<=(n+m)) lim<<=1;
NTT(a,lim,1); NTT(b,lim,1);
rep(i,0,lim-1) ckmul(a[i],b[i]);
NTT(a,lim,-1);
a.resize(n+m-1);
return a;
}
inline poly Get_Line(int x){
vector<int> a,b; a.resize(x+1); b.resize(x+1);
for(int i=0;i<=x;++i){
if(i&1) a[i]=mod-ifac[i]; else a[i]=ifac[i];
b[i]=mul(ifac[i],ksm(i,x));
}
poly vec=Mul(a,b); vec.resize(x+1);
return vec;
}
inline poly solve(int l,int r){
if(l==r){
poly str=Get_Line(c[l]);
poly ret; ret.resize(c[l]+2);
rep(i,0,c[l]) ret[i+1]=mul(str[i],fac[i]);
return ret;
}
int mid=(l+r)>>1;
return Mul(solve(l,mid),solve(mid+1,r));
}
signed main(){
n=5e5; fac[0]=inv[0]=1;
for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
ifac[n]=ksm(fac[n],mod-2);
Down(i,n,1) ifac[i-1]=mul(ifac[i],i),inv[i]=mul(ifac[i],fac[i-1]);
n=read(); w=read();
int sumc=0;
rep(i,1,n) sumc+=(c[i]=read());
vector<int> f=solve(1,n);
int ans=0,dfac=1;
for(int i=0;i<=n+sumc;++i){
if(i-n>w) break;
if(i>=n){
ckadd(ans,mul(f[i],mul(dfac,ifac[i])));
}
ckmul(dfac,(w+n-i)%mod);
}
print(ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律