bzoj 4403 序列统计

LINK:序列统计

上一道有点难度的题目。

从题中可以得到 每个数字可以用无限次 且这些数字是有序的。

不难列出来dp式 但是那个好像太慢了 考虑一个式子 \(\sum_{i=l}^{r}x_i=n\)

显然我们要求出所有构成\(x_i\)的方案数 这个式子上隔板法即可。

现在问题求出\(\sum_{i=1}^{n}C(i+w-1,w-1)\)

我通过数形结合 推出了上述式子等于\(C(n+w,w)-1\)

当然还有其他方法 配以一个C(w,w)-1 上述式子按照基本组合数公式也可以额化简为C(n+w,w)-1.

上卢卡斯定理即可。

const int MAXN=1000010;
int n,L,R,T,maxx;
ll fac[MAXN],inv[MAXN];
inline int ksm(ll b,int p){ll cnt=1;while(p){if(p&1)cnt=cnt*b%mod;b=b*b%mod;p=p>>1;}return cnt;}
inline void prepare()
{
	fac[0]=1;
	rep(1,maxx,i)fac[i]=fac[i-1]*i%mod;
	inv[maxx]=ksm(fac[maxx],mod-2);
	fep(maxx-1,0,i)inv[i]=inv[i+1]*(i+1)%mod;
}
inline ll C(int a,int b){if(b>a)return 0;return fac[a]*inv[b]%mod*inv[a-b]%mod;}
inline ll Lucas(int a,int b)
{
	if(b>a)return 0;
	if(a<=maxx)return C(a,b);
	return Lucas(a/mod,b/mod)*Lucas(a%mod,b%mod)%mod;
}
int main()
{
	freopen("1.in","r",stdin);
	maxx=mod-1;get(T);prepare();
	while(T--)
	{
		get(n);get(L);get(R);
		int w=R-L+1;
		put(((Lucas(n+w,w)-1)+mod)%mod);
	}
	return 0;
}
posted @ 2020-03-26 22:09  chdy  阅读(133)  评论(0编辑  收藏  举报