【BZOJ4403】序列統計(組合數學,盧卡斯定理)

#【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;
}
相關文章
相關標籤/搜索