Problem B. Harvest of Apples

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;
}

猜你喜欢

转载自blog.csdn.net/qq_36424540/article/details/81391241