题意
给定三个正整数N、L和R,统计长度在1到N之间,元素大小都在L到R之间的单调不降序列的数量。输出答案对10^6+3取模的结果。
自己xjbyy的解法
设m=r-l+1.
那么我们先枚举一个i表示这个单调不降序列有多少个不同的数, 那么
Cin
就是选出i个不同的数的方案数,然后我们看剩下的n-i个数,很明显他们可以不选,或者成为这i个数中的一个,此时就对应球盒模型“n-i个相同的球放入i个盒子,盒子可以为空的方案数”,因为球可以不放,我们就新增一个盒子不放的球单独放到这个盒子里,哪么就是“n-i个相同的球放入i+1个盒子,盒子可以为空的方案数”了,这个就等于
Cim
于是最后的答案就是
∑ni=1CinCim
,然后我们可以考虑化简他:
原式=
∑ni=1CinCm−im
我们考察一下这个式子的意义,就是有两个盒子,一个盒子有n个球,一个盒子有m个球,然后一个盒子选i个球
1<=i<=n
,两个盒子一共选m个球的方案数,所以我们完全可以把两个盒子的球混在一起然后选出m个球,那就是
Cmn+m
了,我们发现,这样算的话,i=0这种情况也被算进去了,所以我们应该再减去一个1,哪么最后的答案就是
Cmn+m−1
了。
r
突然清醒
突然发现自己是zz:我们这个问题就直接相当于把”n个球放入m个盒子,盒子可以为空,球可以不选”,再减去n个球一个都不选的情况,那就直接是 Cmn+m -1了.
#include<cstdio>
#include<algorithm>
const int P = 1e6 + 3;
typedef long long ll;
int T, n, m;
ll jx[P], jx_rev[P];
int C (int n, int m) {
if (m > n) return 0;
return jx[n] * jx_rev[m] % P * jx_rev[n - m] % P;
}
ll Lucas (int n, int m) {
if (m > n) return 0ll;
if (n < P) return C (n, m);
int k = C (n % P, m % P);
if (k) return Lucas (n / P, m / P) * k % P;
return 0ll;
}
ll quick_power (ll a, ll b) {
ll ret = 1;
for (; b; a = a * a % P, b >>= 1) if (b & 1) ret = ret * a % P;
return ret;
}
int main () {
scanf ("%d", &T);
int l, r;
jx[0] = 1; for (int i = 1; i < P; ++i) jx[i] = jx[i - 1] * i % P;
jx_rev[P - 1] = quick_power (jx[P - 1], P - 2);
for (int i = P - 2; ~i; --i) jx_rev[i] = jx_rev[i + 1] * (i + 1) % P;
while (T--) {
scanf ("%d%d%d", &n, &l, &r), m = r - l + 1;
printf ("%lld\n", (Lucas (n + m, m) - 1 + P) % P);
}
return 0;
}