#【BZOJ4403】序列統計(組合數學,盧卡斯定理) ##題面 ###Descriptionios
給定三個正整數N、L和R,統計長度在1到N之間,元素大小都在L到R之間的單調不降序列的數量。輸出答案對10^6+3取模的結果。 ###Input 輸入第一行包含一個整數T,表示數據組數。 第2到第T+1行每行包含三個整數N、L和R,N、L和R的意義如題所述。 1≤N,L,R≤10^9,1≤T≤100,輸入數據保證L≤R。 ###Outputspa
輸出包含T行,每行有一個數字,表示你所求出的答案對10^6+3取模的結果。 ###Sample Input 2code
1 4 5ip
2 4 5 ###Sample Output 2get
5 ##題解 $L,R$不就是搞笑的嗎? 直接向左平移$L-1$個單位就行了。。。 如下的$X=R-(L-1)$數學
如今,認真的來解決問題 考慮這樣一道小學奧數題: 有$n$個相同的小球,要放進$m$個不一樣的盒子裏 每一個盒子能夠爲空,求放的方案數string
先給每一個盒子人爲的放一個小球 再用隔板法計算 答案爲$C_{n+m-1}^{m-1}$it
如今,這個問題不就是同樣的嗎? 至關於有X個盒子,分別表明着X個數字 如今有$i$個小球,求放法總數 其中$i\in [1,n]$ 因此,所求爲: $\sum_{i=1}^nC_{i+X-1}^{X-1}$ 化簡一下 $C_{n+X}^X-1$ 而後盧卡斯一波就能夠啦io
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define MOD 1000003 #define MAX (MOD+1000) #define ll int ll n,L,R; ll jc[MAX],inv[MAX]; inline int read() { int x=0,t=1;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } ll fpow(ll a,ll b) { ll s=1; while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;} return s; } ll C(ll m,ll n) { if(n<m)return 0; return 1ll*jc[n]*inv[m]%MOD*inv[n-m]%MOD; } ll Lucas(ll m,ll n) { if(n<m)return 0; if(m==0)return 1; return (1ll*Lucas(m/MOD,n/MOD)*C(m%MOD,n%MOD))%MOD; } int main() { int T;T=read(); jc[0]=inv[0]=1; for(int i=1;i<MOD;++i)jc[i]=1ll*jc[i-1]*i%MOD; inv[MOD-1]=fpow(jc[MOD-1],MOD-2); for(int i=MOD-2;i;--i)inv[i]=1ll*inv[i+1]*(i+1)%MOD; while(T--) { n=read();L=read();R=read(); R-=L-1; printf("%d\n",(Lucas(R,n+R)-1+MOD)%MOD); } return 0; }