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