4403: 序列统计
Time Limit: 3 Sec Memory Limit: 128 MB
Submit: 1348 Solved: 611
Description
给定三个正整数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。
Output
输出包含T行,每行有一个数字,表示你所求出的答案对10^6+3取模的结果。
Sample Input
2
1 4 5
2 4 5
Sample Output
2
5
//【样例说明】满足条件的2个序列为[4]和[5]。
解析:
最初理解错了题意,这里的长度就是数的个数!
令r-l+1=m,也就是一共有m个数可选,那么设每一个数被选的个数为xi,那么x1+x2+…+xm=n
也就相当于将n个小球放到m个盒子里,显然是插板法。答案为
那么这道题的答案就是
在前面加一项,再根据将相邻两项合并
那么答案就是
这里提一下插板法。
简单的例子,把5个相同的球分给3个人,要求每人至少拿到一个球,有几种分法?
用隔板法解很简单,把5个球放成一排
o , o , o , o , o
中间有4个间隔位置(逗号的位置),选出两个放入隔板,比如
o | o o | o o
就对应于一种分配方式
所以总共有C(2,4)=6种分配方式
一般地,把n个相同的球分给k个人,要求每人至少拿到一个球,有C(k-1,n-1)种分法
类似的例子,x1+x2+...+xn=k的正整数解的个数也这样解
稍微变形一点的例子,把n个相同的球分给k个人,但不要求每人至少拿到一个球,有几种分法(其实就是这道题)?也用隔板法,先去借k个球过来,再把n+k个球分给k个人,要求每人至少拿一个,有C(k-1,n+k-1)种分法,然后从每人手里收回一个还债就行了。
代码:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int mod=1000003;
const int Max=1000005;
int t,n,l,r,ans;
int mul[Max],inv[Max];
inline void pre()
{
mul[1]=1,mul[0]=1;
for(int i=2;i<=mod;i++) mul[i]=((LL)i * (LL)mul[i-1]) % mod;
inv[1]=1,inv[0]=1;
for(int i=2;i<=mod;i++) inv[i] = (LL)(mod - mod/i) * (LL)inv[mod % i] % mod;
}
inline int C(int n,int m)
{
if(m>n)return 0;
return (LL)mul[n] * (LL)inv[mul[m]] % (LL)mod * inv[mul[n-m]] % mod;
}
inline int Lucas(int n,int m)
{
if(!m) return 1;
else return ((LL)C(n%mod,m%mod) % mod * (LL)Lucas(n/mod,m/mod) % mod) % mod;
}
int main()
{
pre();
cin>>t;
while(t--)
{
cin>>n>>l>>r;
ans = ((Lucas(r-l+1+n,r-l+1) - 1) % mod + mod) % mod;
cout<<ans<<"\n";
}
return 0;
}