Problem Description
There are n apples on a tree, numbered from 1 to n.
Count the number of ways to pick at most m apples.
Input
The first line of the input contains an integer T (1≤T≤105) denoting the number of test cases.
Each test case consists of one line with two integers n,m (1≤m≤n≤105).
Output
For each test case, print an integer representing the number of ways modulo 109+7.
Sample Input
2
5 2
1000 500
Sample Output
16
924129523
#include<bits/stdc++.h>
using namespace std;
//现在比较水,没理解到根,先不写题解了
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
const int maxn=1e5+10;
const int mod=1e9+7;
ll block;
struct Query{
ll i,l,r;
bool operator<(const Query& obj)const{
if(l/block==obj.l/block)return r<obj.r;
return l/block<obj.l/block;
}
}query[maxn];
ll fac[maxn],inv[maxn];
ll ans[maxn];
ll pow_mod(ll base,int n){
ll ans=1;
while(n){
if(n&1)ans=(ans*base)%mod;
base=(base*base)%mod;
n>>=1;
}
return ans%mod;
}
//!!!inv的线性求法
void init(){
fac[0]=1;
for(int i=1;i<maxn;i++)fac[i]=fac[i-1]*i%mod;
inv[maxn-1]=pow_mod(fac[maxn-1],mod-2);
for(int i=maxn-2;i>=0;i--){
inv[i]=inv[i+1]*(i+1)%mod;
}
}
ll C(ll n,ll m){
if(n==m||m==0)return 1;
if(m>n)return 0;
//printf("fac(%lld):%lld inv(%lld):%lld inv(%lld):%lld\n",r,fac[r],l,inv[l],r-l,inv[r-l]);
return (((fac[n]*inv[m])%mod)*inv[n-m])%mod;
}
/*
1
3 1
3 2
*/
int main(){
init();
//printf("C(%d,%d):%lld\n",3,4,C(3,4));
int m;
scanf("%d",&m);
ll max_dis=0;
for(int i=0;i<m;i++){
scanf("%lld %lld",&query[i].l,&query[i].r);
query[i].i=i;
max_dis=max(max_dis,query[i].l);
}
block=sqrt(max_dis);
sort(query,query+m);
ll l=1,r=1;
ll res=2;
for(int i=0;i<m;i++){
while(l<query[i].l){
res=(2*res-C(l,r)+mod)%mod;
l++;
}
while(l>query[i].l){
l--;
res=((res+C(l,r))%mod*inv[2])%mod;
}
while(r<query[i].r){
r++;
res=(res+C(l,r))%mod;
}
while(r>query[i].r){
res=(res-C(l,r)+mod)%mod;
r--;
}
ans[query[i].i]=res;
}
for(int i=0;i<m;i++){
printf("%lld\n",ans[i]);
}
return 0;
}