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.
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).
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
Source
Recommend
莫队,O(1)转移为:f(n,m+1)=f(n,m)+C(n,m+1)
f(n+1,m)=2f(n,m)-C(n,m).
#include <bits/stdc++.h>
#define maxn 100505
using namespace std;
typedef long long ll;
const ll mod =1e9+7;
struct node
{
ll l,r,pos;
}query[maxn];
ll block;
ll fact[maxn],inv[maxn];
ll Pow(ll x,ll n){
ll ans=1,base=x;
while(n){
if(n&1) ans=ans*base%mod;
base=base*base%mod;
n>>=1;
}
return ans;
}
void init(){
fact[0]=1;
for (int i = 1; i < maxn; ++i)
{
fact[i]=fact[i-1]*i%mod;
}
inv[maxn-1]=Pow(fact[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;
return ((long long)fact[n]*inv[m]%mod)*inv[n-m]%mod;
}
bool cmp(node a,node b)
{
if((a.l/block)==(b.l/block))
{
return a.r<b.r;
}
return ((a.l/block)<(b.l/block));
}
ll ans[maxn];
int main()
{
ll t,i;
init();
//cout<<C(6,4)<<endl;
scanf("%lld",&t);
ll maxim=0;
for(i=1;i<=t;i++)
{
scanf("%lld%lld",&query[i].l,&query[i].r);
query[i].pos=i;
maxim=max(maxim,query[i].l);
}
block=sqrt(maxim);
sort(query+1,query+1+t,cmp);
ll le=1,ri=1;
ll now=2;//le=n,ri=m;
for(i=1;i<=t;i++)
{
while(le<query[i].l)
{
now=(2*now-C(le,ri)+mod)%mod;
le++;
}
while(le>query[i].l)
{ le--;
now=((now+C(le,ri))%mod*inv[2]%mod)%mod;
}
while(ri<query[i].r)
{ ri++;
now=(now+C(le,ri))%mod;
}
while(ri>query[i].r)
{
now=(now-C(le,ri)+5*mod)%mod;
ri--;
}
ans[query[i].pos]=now;
}
for(i=1;i<=t;i++)
{
printf("%lld\n",ans[i]);
}
return 0;
}

浙公网安备 33010602011771号