要求C (n,0) + C (n,1) + C (n,2) + … + C (n,m)
即S (n,m)
很明显,S (n,m) = S (n,m-1) + C (n,m)
由杨辉三角可以得到,S (n,m) = 2 * S (n-1,m) - C (n-1, m)
然后就用莫队,暴力(优雅…)地求出每个答案
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
#include<bitset>
#include<unordered_map>
using namespace std;
#define LL long long
#define eps (1e-9)
typedef unsigned long long ull;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const int bas = 131;
const LL mod = 1e9 + 7;
int block;
LL fac[maxn + 10], inv[maxn + 10];
LL ans[maxn];
LL qpow(LL a, LL b)
{
LL res = 1;
while (b)
{
if (b & 1)res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void init()
{
block = sqrt(maxn);//块的大小
fac[0] = 1, inv[0] = 1;
for (LL i = 1; i <= maxn; i++)
{
fac[i] = fac[i - 1] * i % mod;
}
inv[maxn] = qpow(fac[maxn], mod - 2);
for (int i = maxn - 1; i >= 1; i--)
{
inv[i] = inv[i + 1] * (i + 1) % mod;
}
}
struct node
{
int n, m, id;
}a[maxn];
bool cmp(node a, node b)
{
if (a.m / block == b.m / block)return a.n < b.n;
return a.m < b.m;
}
LL cal(int n, int m)
{
return fac[n] * inv[n - m] % mod * inv[m] % mod;
}
int main()
{
init();
int t;
scanf("%d", &t);
for (int i = 1; i <= t; i++)
{
scanf("%d%d", &a[i].n, &a[i].m);
a[i].id = i;
}
sort(a + 1, a + t + 1, cmp);
int L = 0, r = 0;
LL res = 1;
for (int i = 1; i <= t; i++)
{
while (L < a[i].n)res = ((2 * res - cal(L, r)) % mod + mod) % mod, L++;
while (L > a[i].n)L--, res = (res + cal(L, r)) % mod * inv[2] % mod;
while (r < a[i].m)r++, res = (res + cal(L, r)) % mod;
while (r > a[i].m)res = ((res - cal(L, r)) % mod + mod) % mod, r--;
ans[a[i].id] = res;
}
for (int i = 1; i <= t; i++)
{
printf("%lld\n", ans[i]);
}
return 0;
}