harvasst of apples(组合数)(乘法逆元)(莫队算法)

                             Problem B. Harvest of Apples

                 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
                                             Total Submission(s): 1529    Accepted Submission(s): 171

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

扫描二维码关注公众号,回复: 2699072 查看本文章

16

924129523

题意:计算多组C(n,0)~C(n,m)的和

利用c(n,m)=c(n-1,m)+c(n-1,m-1)可以推出以上两个公式。

利用莫队算法时,将(n,m)想想成坐标轴上XY两个变量,每次改变其中一个,直到到达终点。

关于莫队算法:https://blog.csdn.net/sadsummerholiday/article/details/81366875

#include<bits/stdc++.h>
#define maxn 100505
//#define mod 10000007
typedef long long ll;
using namespace std;
ll fac[maxn+50],inv[maxn+50];
int block;
const ll mod=1e9+7;

struct nod
{
    ll l,r,pos;
}query[maxn+50];

ll pow(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 ini()
{
    fac[0]=1;
    for(int i=1;i<=maxn;i++)
        fac[i]=fac[i-1]*i%mod;
    inv[maxn-1]=pow(fac[maxn-1],mod-2);
    for(int i=maxn-2;i>=0;i--)
    {
        inv[i]=inv[i+1]*(i+1)%mod;  //乘起来等于fac[maxn]^(mod-1),模mod也是1
    }
}

bool cmp(nod a,nod b)
{
    if((a.l/block)==(b.l/block))
        return a.r<b.r;
    else
        return ((a.l/block)<(b.l/block));
}

ll C(ll n,ll m)
{
    if(n==m||m==0)
        return 1;
    if(m>n) return 0;
    return ((long long)fac[n]*inv[m]%mod)*inv[n-m]%mod;
}

int main()
{
    ll ans[maxn+50]={0};
    int T,x,y,maxnn=0;
    ini();
    //cout<<C(6,4)<<endl;
    scanf("%I64d",&T);
    for(int i=1;i<=T;i++)
    {
        scanf("%I64d%I64d",&x,&y);
        query[i].l=x;
        query[i].r=y;
        query[i].pos=i;
        maxnn=max(maxnn,x);

    }
    block=sqrt(maxnn);
    sort(query+1,query+T+1,cmp);
    int le=1,ri=1;
    ll now=2;
    for(int i=1;i<=T;i++)
    {
        while(le<query[i].l)
        {
            now=(2*now-C(le,ri)+mod)%mod;
            //printf("%d\n",C(le,ri));
            le++;
        }
        while(le>query[i].l)
        {
            le--;
            now=(now+C(le,ri))%mod*inv[2]%mod;
        }
        while(ri<query[i].r)
        {
            now=(now+C(le,ri+1))%mod;
            ri++;
        }
        while(ri>query[i].r)
        {
            now=(now-C(le,ri)+5*mod)%mod;
            ri--;
        }
        ans[query[i].pos]=now;
    }
    for(int i=1;i<=T;i++)
    {
        printf("%I64d\n",ans[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sadsummerholiday/article/details/81366747