Problem B. Harvest of Apples
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2073 Accepted Submission(s): 804
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
Source
2018 Multi-University Training Contest 4
Recommend
chendu | We have carefully selected several similar problems for you: 6343 6342 6341 6340 6339
#include<iostream>
#include<algorithm>
#include<string>
#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}
#include<vector>
#include<cmath>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define ll long long
#define MAX 1000000000
#define ms memset
using namespace std;
const int mod=1e9+7;
const int maxn=1e5+5;
/*
题目大意:很简洁,求组合数,
观察数据发现查询的数量特别多,
就是说可以预处理查询来简化复杂度。
不难想到莫队算法。
莫队算法也有要求的,要求在O(1)时间内完成
(n,m)到(n-1,m)或(n,m-1)的转移。
那么对于这题,考验点数学思维。
S(n,m)=2*S(n-1,m)-C(n-1,m)
S(n,m)=S(n,m-1)+C(n,m)
莫队转移时注意点即可,其他的没有什么特别的。
这题这代码过不了,但是自己想的所有样例都没问题,
头疼,思路大致是对的,欢迎点出错误。
*/
ll Powmod(ll a,ll b)
{
ll t=1;
while(b)
{
if(b&1) t=1ll*t*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return t;
}
ll jie[maxn+1],inv[maxn+1];///阶乘,和阶乘的逆元
void init()
{
jie[0]=jie[1]=1;
for(int i=2;i<=maxn;i++) jie[i]=(1ll*jie[i-1]*i)%mod;
inv[maxn]=Powmod(jie[maxn],mod-2);
for(int i=maxn-1;~i;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
}
ll C(ll n, ll m)
{
return jie[n]*inv[m] %mod * inv[n-m] %mod;
}
struct node
{
ll l,r,id;
node(){}
};
node q[maxn];
int blocks;
bool cmp(node x,node y)
{
if(x.r/blocks==y.r/blocks) return x.l<y.l;
return x.r<y.r;
}
int main()
{
init();
int mx=100000;
int t;scanf("%d",&t);
for(int i=0;i<t;i++)
{
scanf("%lld%lld",&q[i].r,&q[i].l);
q[i].id=i;
}
blocks=sqrt(mx);
sort(q,q+t,cmp);
ll ans[maxn],l=-1,r=0,res=0;
for(int i=0;i<t;i++)
{
///cout<<q[i].r<<" "<<q[i].l<<endl;
while(r<q[i].r) res=( (res+res)%mod-C(r++,l)+mod )%mod;
while(r>q[i].r) res=(res+C(--r,l))/2,res%=mod;
while(l<q[i].l) res=( res+C(r,++l) )%mod;
while(l>q[i].l) res=(res-C(r,l--)+mod)%mod;
ans[q[i].id]=res;
}
for(int i=0;i<t;i++) printf("%lld\n",ans[i]);
return 0;
}