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

題解:題目要求累加組合C(n,m)m的範圍(0,m);所以如果用莫隊最重要的是 弄清相鄰的總和之間的關係

         並且要明白組合是如何在編程中實現的,例如C(n,m)爲1到n的累乘,乘以n-m的逆元進行mod運算,乘以m的逆元再進行mod運算。

         逆元則是當前數的mod-2次方,最好在用之前就把累乘表和逆元表打好;

#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define maxn 100005
#define ll long long
ll inv[maxn],fas[maxn],ans[maxn];
int pos[maxn];//記錄數據所屬的塊
struct node
{
    int n,m,id;
}a[maxn];
bool cmp(node o,node p)
{
    return pos[o.n]==pos[p.n]?o.m<p.m:o.n<p.n;
}
ll qpow(ll a,ll b)//快速冪
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        {
           ans=ans*a%mod;
        }
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
void init()
{
    fas[1]=1;
    for(int i=2;i<maxn;i++)//累乘表
    {
        fas[i]=i*fas[i-1]%mod;
    }
    for(int i=1;i<maxn;i++)//逆元表
    {
        inv[i]=qpow(fas[i],mod-2);
    }
}
ll C(int n,int m)//組合運算
{
    if(n<=0||n<m||m<0)
    {
        return 0;
    }
    if(m==0||n==m)
    {
        return 1;
    }
    return fas[n]*inv[n-m]%mod*inv[m]%mod;
}
int main()
{
    init();
    int block=sqrt(maxn),t;
    cin>>t;
    for(int i=1;i<maxn;i++)//進行莫隊的劃塊
    {
        pos[i]=(i-1)/block;
    }
    for(int i=1;i<=t;i++)
    {
        scanf("%d %d",&a[i].n,&a[i].m);
        a[i].id=i;
    }
    sort(a+1,a+1+t,cmp);//莫隊排序
    int st=1,en=0;
    ll dns=1;
    for(int i=1;i<=t;i++)
    {
        while(st<a[i].n)
        {
            dns=(2*dns-C(st++,en)+mod)%mod;
        }
        while(st>a[i].n)
        {
            dns=(dns+C(--st,en))*inv[2]%mod;
        }
        while(en<a[i].m)
        {
            dns=(dns+C(st,++en))%mod;
        }
        while(en>a[i].m)
        {
            dns=(dns-C(st,en--)+mod)%mod;
        }
        ans[a[i].id]=dns;
    }
    for(int i=1;i<=t;i++)//輸出結果
    {
        printf("%lld\n",ans[i]);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章