Problem B. Harvest of Apples
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2601 Accepted Submission(s): 1002
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
题意:T个询问,每次询问输出Cn0 Cn1 Cn2 ......Cnm的和模109+7
思路:首先要得到S(n,m)=S(n,m−1)+C(n m),S(n,m)=2S(n−1,m)−C(n−1 m)这两个式子,后一个式子可以用杨辉三角得出,然后用莫队搞一下就行了
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int MOD = 1000000007;
struct node
{
int l,r,id;
int ans;
}q[MAXN];
int unit;
ll ans[MAXN],sum;
ll fac[MAXN],inv[MAXN];
ll inv2;
bool cmp(const struct node& a,const struct node& b)
{
if(a.l / unit == b.l / unit) return a.r < b.r;
else return a.l / unit < b.l / unit;
}
ll q_pow(ll a,int b)
{
ll res = 1,base = a;
while(b) {
if(b & 1) res = res * base % MOD;
base = base * base % MOD;
b >>= 1;
}
return res;
}
ll Comb(int n,int k)
{
return fac[n] * inv[k] % MOD * inv[n - k] % MOD;
}
void init()
{
inv2 = q_pow(2,MOD - 2);
fac[0] = fac[1] = 1;
for(int i = 2; i < MAXN; i++) {
fac[i] = i * fac[i - 1] % MOD;
}
inv[MAXN - 1] = q_pow(fac[MAXN - 1],MOD - 2);
for(int i = MAXN - 2; i >= 0; i--) {
inv[i] = inv[i + 1] * (i + 1) % MOD;
}
}
void add_n(int L,int R)
{
sum = (2 * sum % MOD - Comb(L - 1,R) + MOD) % MOD;
}
void sub_n(int L,int R)
{
sum = (sum + Comb(L - 1,R)) % MOD * inv2 % MOD;
}
void add_m(int L,int R)
{
sum = (sum + Comb(L,R)) % MOD;
}
void sub_m(int L,int R)
{
sum = (sum - Comb(L,R) + MOD) % MOD;
}
int main(void)
{
int T;
init();
unit = sqrt(MAXN * 1.0);
scanf("%d",&T);
for(int i = 1; i <= T; i++) {
scanf("%d %d",&q[i].l,&q[i].r);
q[i].id = i;
}
sum = 2;
sort(q + 1,q + T + 1,cmp);
int prel = 1,prer = 1;
for(int i = 1; i <= T; i++) {
while(q[i].l > prel) add_n(++prel,prer);
while(q[i].l < prel) sub_n(prel--,prer);
while(q[i].r > prer) add_m(prel,++prer);
while(q[i].r < prer) sub_m(prel,prer--);
ans[q[i].id] = sum;
}
for(int i = 1; i <= T; i++) {
printf("%lld\n",ans[i]);
}
return 0;
}