CF1548C The Three Little Pigs
链接
分析
发现题目求 \(\sum\limits_{i=1}^{n}\dbinom {3i}x\)。
这里有一个结论,对任意正整数 \(x\),\(\sum\limits_{i=1}^{n}\dbinom i x=\dbinom {n+1}{x+1}\)。
证明可以考虑数学归纳法:
当 \(n=1\) 时,\(\dbinom 1 x=\dbinom 2{x+1}=[x=1]\),命题成立;
当 \(n=k(k>1)\) 时,\(\sum\limits_{i=1}^{k}\dbinom i x=\sum\limits_{i=1}^{k-1}\dbinom i x+\dbinom kx=\dbinom k{x+1}+\dbinom kx=\dbinom{k+1}{x+1}\),命题成立。
所以我们发现这两个式子有点像,试着套一下,\(\sum\limits_{i=1}^{3n}\dbinom i x=\dbinom {3n+1}{x+1}\),然后看它们的区别。
\(\dbinom {3n+1}{x+1}=\sum\limits_{i=1}^{3n}\dbinom i x=\sum\limits_{i=1}^{n}\dbinom {3i}x+\sum\limits_{i=1}^{n}\dbinom {3i-1}x+\sum\limits_{i=1}^{n}\dbinom {3i-2}x\)。
所以我们设 \(A(x)=\sum\limits_{i=1}^{n}\dbinom {3i}x,B(x)=\sum\limits_{i=1}^{n}\dbinom {3i-1}x,C(x)=\sum\limits_{i=1}^{n}\dbinom {3i-2}x\)。
我们发现 \(A(x)+B(x)+C(x)=\dbinom {3n+1}{x+1}\),于是观察这三者之间的联系。
注意到继续利用 \(\dbinom n m=\dbinom {n-1}{m-1}+\dbinom{n-1} m\),
我们有 \(A(x)=B(x)+B(x-1),B(x)=C(x)+C(x-1)\)。
于是我们就有三个方程三个未知数,就可以递推求解所有 \(A\) 了。
时间复杂度 \(O(n)\)。
code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define in read()
inline int read(){
int p=0,f=1;
char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){p=p*10+c-'0';c=getchar();}
return p*f;
}
const int N=3e6+5;
const int mod=1e9+7;
int n,m,fact[N],invfact[N],inv3;
inline int add(int x,int y){int z=x+y;return z>=mod?z-mod:z;}
inline void Add(int &x,int y){x=add(x,y);}
inline int mul(int x,int y){int z=x*y;return z>=mod?z%mod:z;}
inline void Mul(int &x,int y){x=mul(x,y);}
inline int qpow(int a,int b){int ans=1;for(;b;Mul(a,a),b>>=1)if(b&1)Mul(ans,a);return ans;}
inline int binom(int n,int m){return n<m?0:mul(mul(fact[n],invfact[m]),invfact[n-m]);}
inline void pro(){
fact[0]=1;
for(int i=1,r=n*3+1;i<=r;i++)
fact[i]=mul(i,fact[i-1]);
invfact[3*n+1]=qpow(fact[3*n+1],mod-2);
for(int i=n*3;i>=0;i--)
invfact[i]=mul(invfact[i+1],i+1);
}
int A[N],B[N],C[N];
signed main(){
n=in,m=in,pro(),inv3=qpow(3,mod-2);
A[1]=mul(mul(mul(n,n+1),3),invfact[2]);
B[1]=add(A[1],mod-n),C[1]=add(B[1],mod-n);
for(int i=2;i<=3*n;i++){
C[i]=mul(inv3,add(add(binom(3*n+1,i+1),add(mod-C[i-1],mod-C[i-1])),mod-B[i-1]));
B[i]=add(C[i],C[i-1]);
A[i]=add(B[i],B[i-1]);
}
for(int i=1,x;i<=m;i++)
x=in,cout<<A[x]<<'\n';
return 0;
}