【CF1548C】The Three Little Pigs

题目

题目链接:https://codeforces.com/contest/1548/problem/C
给定 \(n,Q\)\(Q\) 次询问,每次询问给出 \(k\),求

\[\sum^{n}_{i=1}\binom{3i}{k}\bmod 10^9+7 \]

\(n\leq 10^6,Q\leq 2\times 10^5\)

思路

\(f[i][j]=\sum^{n-1}_{k=0}\binom{3k+j}{i}\bmod 10^9+7\) 的值。其中 \(j\in [0,2]\)。这样的话,答案就是 \(f[k][0]+\binom{3n}{k}\) 了。
考虑怎么转移。根据 \(\binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1}\),有

\[f[i][1]=f[i][0]+f[i-1][0] \]

\[f[i][2]=f[i][1]+f[i-1][1] \]

然后观察到

\[f[i][0]+f[i][1]+f[i][2]=\sum^{3n-1}_{j=0}\binom{j}{i}=\binom{3n}{i+1} \]

就可以进行 dp 预处理出 \(f[i][j]\) 了。
至于 \(\sum^{3n-1}_{j=0}\binom{j}{i}=\binom{3n}{i+1}\) 的原因,考虑组合意义,“从 \(3n\) 个物品选出 \(i+1\) 个”。当最后一个被选择的物品是第 \(k\) 个时,方案数就等于 \(\binom{k-1}{i}\)
时间复杂度 \(O(n+Q)\)

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=3000010,MOD=1e9+7,inv3=333333336;
int n,Q,f[N][3];
ll fac[N],inv[N];

ll fpow(ll x,ll k)
{
	ll ans=1;
	for (;k;k>>=1,x=x*x%MOD)
		if (k&1) ans=ans*x%MOD;
	return ans;
}

ll C(int n,int m)
{
	if (n<m) return 0;
	return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}

int main()
{
	scanf("%d%d",&n,&Q);
	fac[0]=inv[0]=1;
	for (int i=1;i<=3*n;i++) fac[i]=fac[i-1]*i%MOD;
	inv[3*n]=fpow(fac[3*n],MOD-2);
	for (int i=3*n-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%MOD;
	f[0][0]=f[0][1]=f[0][2]=n;
	for (int i=1;i<=3*n;i++)
	{
		f[i][0]=(C(3*n,i+1)-f[i-1][1]-f[i-1][0]*2)*inv3%MOD;
		f[i][1]=(f[i][0]+f[i-1][0])%MOD;
		f[i][2]=(f[i][1]+f[i-1][1])%MOD;
	}
	while (Q--)
	{
		int k;
		scanf("%d",&k);
		cout<<((f[k][0]+C(3*n,k))%MOD+MOD)%MOD<<"\n";
	}
	return 0;
}
posted @ 2021-08-02 22:41  stoorz  阅读(67)  评论(0编辑  收藏  举报