题干:
There are nn apples on a tree, numbered from 11 to nn. 
 Count the number of ways to pick at most mm apples. 
Input
The first line of the input contains an integer TT (1≤T≤105)(1≤T≤105) denoting the number of test cases. 
 Each test case consists of one line with two integers n,mn,m (1≤m≤n≤105)(1≤m≤n≤105). 
Output
For each test case, print an integer representing the number of ways modulo 109+7109+7.
Sample Input
2
5 2
1000 500Sample Output
16
924129523解题报告:
不得不说,一道好题。
会者不难,难者不会。
刚开始想到离线了。这么想的:想着组合数公式打表,但是空间复杂度不容许,然后像滚动数组优化,自然而然就想到离线了,这样跑下来就相当于是求了一遍1e5的组合数。(相当于n^2了)然而超时了。
正解是这样的,(链接)首先我们要知道组合数和杨辉三角存在着密切的关系?(貌似是高中讲二项式定理的时候提到的)

AC代码:
using namespace std;
const int MAX = 1e5 + 5;
const ll mod = 1000000007;
ll jie[MAX],inv[MAX],q[MAX];
struct Node {
  int l , r,block,id;
} node[MAX];
//bool cmp(Node a,Node b) {
//  if(a.block == b.block) return a.r < b.r;
//  else return a.l < b.l;
//}
//这样分块貌似会快不少?
bool cmp(Node a,Node b) {
  if (a.block!=b.block) return a.l<b.l;
  if (a.block&1) return a.r>b.r;
  return a.r<b.r;
}
//这个c函数是错的。。。貌似就是因为没有判断r<l的情况?
//ll c(ll n,ll m) {
//  return jie[n]*(jie[m]%mod*jie[n-m]%mod);
//}
ll c(int r,int l) {
  if (r<l) return 0;
  return jie[r]*inv[l]%mod*inv[r-l]%mod;
}
int main()
{
  jie[1] = 1;jie[0] = 1;
  inv[1] = 1;inv[0] = 1;
  for(int i = 2; i<=MAX-1; i++) jie[i] = (jie[i-1] * i)%mod;
  for(int i = 2; i<=MAX-1; i++) {
    inv[i] = (mod - mod/i*inv[mod%i]%mod)%mod;
  }
//这两个求逆元的公式都可以使用
//  for (int i=2; i<MAX; i++) {
//    inv[i]=inv[mod%i]*(mod-mod/i)%mod;
//  }
//预处理逆元的前缀积
  for (int i=2; i<MAX; i++) inv[i]=inv[i-1]*inv[i]% mod;
  int t;
  cin>>t;
  int blk = sqrt(100000);
  for(int i = 1; i<=t; i++) {
    scanf("%d%d",&node[i].r,&node[i].l);
    node[i].id = i;
    node[i].block = node[i].l/blk;
  }
  int l=1,r=1;
  ll ans = 2;
  sort(node+1,node+t+1,cmp);
  for(int i = 1; i<=t; i++) {
    while(l < node[i].l) l++,ans = (ans + c(r,l))%mod;
    while(l > node[i].l) ans = (ans - c(r,l) + mod) % mod,l--;
    while(r < node[i].r) r++,ans = (2*ans-c(r-1,l) + mod )%mod;
    while(r > node[i].r) ans = (ans + c(r-1,l)) * inv[2] % mod,r--;
    q[node[i].id] = ans;
  } 
  for(int i = 1; i<=t; i++) printf("%lld\n",q[i]);
  return 0 ;
}
                




