2018.09.09 bzoj4403: 序列统计(Lucas定理)

传送门
感觉单调不降序列什么的不好做啊。
于是我们序列中下标为i的元素的值加上i,这样就构成了一个单调递增的序列。
问题就变成了:
求出构造长度分别为1 ~ n且每个元素的值在l+1 ~ r+n之间的单调递增的序列的总方案数。
那么对于一个长度为i的序列,构造出的方案数显然就是(r−l+ii)=(r−l+ir−l)\binom {r-l+i} {i}=\binom {r-l+i} {r-l}(irl+i)=(rlrl+i)
所以答案就是:
∑i=1n(r−l+ir−l)\sum _{i=1} ^n \binom {r-l+i} {r-l}i=1n(rlrl+i)
<=>
(∑i=1n(r−l+ir−l))+(r−l+1r−l+1)−1(\sum _{i=1} ^n \binom {r-l+i} {r-l})+\binom {r-l+1} {r-l+1} -1(i=1n(rlrl+i))+(rl+1rl+1)1
<=>
(∑i=2n(r−l+ir−l))+(r−l+2r−l+1)−1(\sum _{i=2} ^n \binom {r-l+i} {r-l})+\binom {r-l+2} {r-l+1} -1(i=2n(rlrl+i))+(rl+1rl+2)1
<=>
((r−l+nr−l))+(r−l+nr−l+1)−1(\binom {r-l+n} {r-l})+\binom {r-l+n} {r-l+1} -1((rlrl+n))+(rl+1rl+n)1
<=>
((r−l+nr−l))+(r−l+nr−l+1)−1(\binom {r-l+n} {r-l})+\binom {r-l+n} {r-l+1} -1((rlrl+n))+(rl+1rl+n)1
<=>
(r−l+n+1r−l+1)−1\binom {r-l+n+1} {r-l+1}-1(rl+1rl+n+1)1
然后就可以上lucas了
代码:

#include<bits/stdc++.h>
#define mod 1000003
#define ll long long
using namespace std;
int T_T;
ll n,l,r,fac[mod+5],ifac[mod+5];
inline ll lucas(ll a,ll b){
	if(a<b)return 0;
	if(a<mod&&b<mod)return fac[a]*ifac[b]%mod*ifac[a-b]%mod;
	return lucas(a%mod,b%mod)*lucas(a/mod,b/mod)%mod;
}
int main(){
	scanf("%d",&T_T),fac[0]=1,ifac[1]=ifac[0]=1;
	for(ll i=1;i<mod;++i)fac[i]=fac[i-1]*i%mod;
	for(ll i=2;i<mod;++i)ifac[i]=(mod-mod/i)*ifac[mod%i]%mod;
	for(ll i=2;i<mod;++i)(ifac[i]*=ifac[i-1])%=mod;
	while(T_T--)scanf("%lld%lld%lld",&n,&l,&r),printf("%lld\n",(lucas(n+r-l+1,r-l+1)+mod-1)%mod);
	return 0;
}

转载于:https://www.cnblogs.com/ldxcaicai/p/9738297.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值