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

版权声明:随意转载哦......但还是请注明出处吧: https://blog.csdn.net/dreaming__ldx/article/details/82557530

传送门
感觉单调不降序列什么的不好做啊。
于是我们序列中下标为i的元素的值加上i,这样就构成了一个单调递增的序列。
问题就变成了:
求出构造长度分别为1~n且每个元素的值在l+1~r+n之间的单调递增的序列的总方案数。
那么对于一个长度为i的序列,构造出的方案数显然就是 ( r l + i i ) = ( r l + i r l )
所以答案就是:
i = 1 n ( r l + i r l )
<=>
( i = 1 n ( r l + i r l ) ) + ( r l + 1 r l + 1 ) 1
<=>
( i = 2 n ( r l + i r l ) ) + ( r l + 2 r l + 1 ) 1
<=>
( ( r l + n r l ) ) + ( r l + n r l + 1 ) 1
<=>
( ( r l + n r l ) ) + ( r l + n r l + 1 ) 1
<=>
( r l + n + 1 r l + 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;
}

猜你喜欢

转载自blog.csdn.net/dreaming__ldx/article/details/82557530