有T组询问,求数字在L,R间长度为1~N的不降序列方案数数(mod 10^6+3)。
,1≤N,L,R≤10^9,1≤T≤100
解
显然可以令(R=R-L+1),不会影响结果,而不降序列正好与可重组合一一对应,因为一种可重组合有且仅有一种一一对应的方案,根据下标公式,于是不难得知答案应为
[C_{R-1+1}^{R-1}+C_{R-1+2}^{R-1}+...+C_{R-1+N}^{R-1}=
]
[C_R^R+C_{R-1+1}^{R-1}+C_{R-1+2}^{R-1}+...+C_{R-1+N}^{R-1}-C_{R}^R=
]
[C_{R+N}^R-1
]
用lucus定理套公式即可。
参考代码:
#include <iostream>
#include <cstdio>
#define il inline
#define ri register
#define ll long long
#define yyb 1000003
using namespace std;
int jc[yyb],jv[yyb];
il void prepare();
il int pow(int,int),lucus(int,int),
C(int,int);
int main(){
int t,n,l,r;
scanf("%d",&t),prepare();
while(t--)scanf("%d%d%d",&n,&l,&r),r-=l-1,
printf("%d
",(lucus(r+n,r)-1+yyb)%yyb);
return 0;
}
il int lucus(int n,int r){
int ans(1);
while(r)ans=(ll)ans*C(n%yyb,r%yyb)%yyb,
n/=yyb,r/=yyb;
return ans;
}
il int C(int n,int r){
if(n<r)return 0;
return (ll)jc[n]*jv[r]*jv[n-r]%yyb;
}
il int pow(int x,int y){
int ans(1);
while(y){
if(y&1)ans=(ll)ans*x%yyb;
x=(ll)x*x%yyb,y>>=1;
}return ans;
}
il void prepare(){
int i;
for(i=jc[0]=1;i<yyb;++i)
jc[i]=(ll)jc[i-1]*i%yyb;
--i,jv[i]=pow(jc[i],yyb-2),jv[0]=1;
while(i>1)jv[i-1]=(ll)jv[i]*i%yyb,--i;
}