题目大意:
给定三个正整数N、L和R,统计长度在1到N之间,元素大小都在L到R之间的单调不降序列的数量。输出答案对10^6+3取模的结果。
1
≤
N
,
L
,
R
≤
1
0
9
,
1
≤
T
≤
100
,
L
≤
R
1≤N,L,R≤10^9,1≤T≤100,L≤R
1≤N,L,R≤109,1≤T≤100,L≤R
分析:
元素在
[
L
,
R
]
[L,R]
[L,R]选其实相当于在
[
1
,
R
−
L
+
1
]
[1,R-L+1]
[1,R−L+1]选
问题转换成,
将
i
i
i个(
i
∈
[
1
,
n
]
i∈[1,n]
i∈[1,n])球放到
R
−
L
+
1
R-L+1
R−L+1个盒子内,盒子可以为空的方案数
a
n
s
=
∑
i
=
1
n
C
i
+
(
R
−
L
)
R
−
L
ans=\sum_{i=1}^{n}C_{i+(R-L)}^{R-L}
ans=∑i=1nCi+(R−L)R−L
也就是
a
n
s
=
C
n
+
(
R
−
L
)
+
1
R
−
L
+
1
−
1
ans=C_{n+(R-L)+1}^{R-L+1}-1
ans=Cn+(R−L)+1R−L+1−1
求C(n,m).但n,m过大时,可用lucas定理
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)
#define lson(x) x * 2
#define rson(x) x * 2 + 1
#define N 1000005
using namespace std;
typedef long long ll;
const int mo = 1000003;
int fac[mo+5], inv[mo+5], ans, T;
void Pre_Work() {
fac[0] = 1; rep(i, 1, mo) fac[i] = (ll)fac[i - 1] * i % mo;
inv[0] = inv[1] = 1; rep(i, 2, mo) inv[i] = (ll)(mo - mo / i) * inv[mo % i] % mo;
inv[0] = 1; rep(i, 1, mo) inv[i] = (ll)inv[i - 1] * inv[i] % mo;
}
int C(int n, int m) {
if (n < m) return 0;
if (n > mo || m > mo) return 1ll * C(n / mo, m / mo) * C(n % mo, m % mo) % mo;
return 1ll * fac[n] * inv[n - m] % mo * inv[m] % mo;
}
int main() {
Pre_Work();
scanf("%d", &T);
int n, L, R;
while (T--) {
scanf("%d %d %d", &n, &L, &R);
R = R - L + 1;
ans = (C(n + R, R) - 1) % mo;
ans = (ans % mo + mo) % mo;
printf("%d\n", ans);
}
return 0;
}
HOME Back