CF1548C The Three Little Pigs

链接

CF1548C

分析

发现题目求 \(\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; 
}
posted @ 2022-02-11 16:27  llmmkk  阅读(27)  评论(0编辑  收藏  举报