题意
给定三个正整数N、LN、LN、L和RRR,统计长度在111到NNN之间,元素大小都在LLL到RRR之间的单调不降序列的数量。输出答案对106+310^6+3106+3取模的结果。
思路
考虑长度为nnn,取值在[1..m][1..m][1..m]间的单调不降序列数量。
对于序列第iii个数,加上i−1i-1i−1,可以转化成求单调上升序列的数量,就是取值为[1..m+n−1][1..m+n-1][1..m+n−1]的单调上升数量。
而这个方案数就为(nm+n−1)\binom{n}{m+n-1}(m+n−1n)
所以统计长度1∼N1\sim N1∼N的答案就为∑i=1n(im+i−1)\sum_{i=1}^{n}\binom{i}{m+i-1}∑i=1n(m+i−1i),化简后得(mn+m)−1\binom{m}{n+m}-1(n+mm)−1
取值在[l..r][l..r][l..r]间,让每个选择的数减去l−1l-1l−1,就是[1..r−l+1][1..r-l+1][1..r−l+1]间。
具体:
代码
#include<cstdio>
#include<algorithm>
const int p = 1e6 + 3;
int n, m;
long long fra[p + 3];
int power(int a, int b) {
long long res = 1;
for (; b; b >>= 1) {
if (b & 1) res = res * a % p;
a = (long long)a * a % p;
}
return res;
}
long long C(long long n, long long m) {
if (n < m) return 0;
return fra[n] * power(fra[m], p - 2) % p * power(fra[n - m], p - 2) % p;
}
long long lucas(long long n, long long m) {
if (!m) return 1;
return C(n % p, m % p) * lucas(n / p, m / p) % p;
}
int main() {
int t, l, r;
scanf("%d", &t);
fra[0] = 1;
for (int i = 1; i <= p; i++)
fra[i] = fra[i - 1] * i % p;
while (t--) {
scanf("%d %d %d", &n, &l, &r);
m = r - l + 1;
printf("%lld\n", ((lucas(n + m, m) - 1) % p + p) % p);
}
}