BZOJ4403: 序列统计【lucas定理+组合数学】

Input

1≤N,L,R≤10^9，1≤T≤100，输入数据保证L≤R。

2
1 4 5
2 4 5

Sample Output

2
5
//【样例说明】满足条件的2个序列为[4]和[5]。

思路

#include<bits/stdc++.h>

using namespace std;

const int Mod = 1e6 + 3;

int f[Mod + 10];
int inv[Mod + 10], fac[Mod + 10];

int add(int a, int b) {
return (a += b) >= Mod ? a - Mod : a;
}

int sub(int a, int b) {
return (a -= b) < 0 ? a + Mod : a;
}

int mul(int a, int b) {
return 1ll * a * b % Mod;
}

int fast_pow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = mul(res, a);
b >>= 1;
a = mul(a, a);
}
return res;
}

void init() {
fac[0] = inv[0] = 1;
for (int i = 1; i < Mod; i++) fac[i] = mul(fac[i - 1], i);
inv[Mod - 1] = fast_pow(fac[Mod - 1], Mod - 2);
for (int i = Mod - 2; i >= 1; i--) inv[i] = mul(inv[i + 1], i + 1);
}

int C(int a, int b) {
return mul(fac[a], mul(inv[b], inv[a - b]));
}

int lucas(int a, int b) {
if (a < b) return 0;
if (a < Mod && b < Mod) return C(a, b);
return mul(C(a % Mod, b % Mod), lucas(a / Mod, b / Mod));
}

int main() {
freopen("input.txt", "r", stdin);
init();
int T; scanf("%d", &T);
while (T--) {
int n, l, r;
scanf("%d %d %d", &n, &l, &r);
printf("%d\n", sub(lucas(r - l + n + 1, n), 1));
}
return 0;
}
posted @ 2018-12-07 21:22  Dream_maker_yk  阅读(...)  评论(...编辑  收藏