Problem B. Harvest of Apples
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2017 Accepted Submission(s): 784
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
预处理逆元参考文章:链接
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int Mod = 1e9 + 7;
const int MAX = 1e5 + 7;
int sz;
struct node{
int l, r, id;
bool operator < (const node &a) const{
if(l / sz == a.l / sz) return r < a.r;
return l < a.l;
}
} a[MAX];
ll res[MAX], ans = 1;
ll fac[MAX], inv[MAX];
ll qpow(ll a, ll b){
ll ans = 1;
while(b){
if(b & 1) ans = (ans * a) % Mod;
b >>= 1;
a = (a * a) % Mod;
}
return ans;
}
void init(){
fac[1] = fac[0] = 1;
for(int i = 2; i <= MAX; i++) fac[i] = fac[i - 1] * i % Mod;
inv[MAX] = qpow(fac[MAX], Mod - 2);
for(int i = MAX - 1; i >= 0; i--)
inv[i] = (inv[i + 1] * (i + 1)) % Mod;
}
ll cnm(ll x, ll y){
return fac[x] * inv[y] % Mod * inv[x - y] % Mod;
}
void del(int l, int r, int flag){
if(flag)
ans = (ans * 2 % Mod - cnm(l, r) + Mod) % Mod;
else
ans = (ans - cnm(l, r) + Mod) % Mod;
}
void add(int l, int r, int flag){
if(flag)
ans = (ans + cnm(l, r)) % Mod * inv[2] % Mod;
else
ans = (ans + cnm(l, r)) % Mod;
}
int main(){
int n;
init();
scanf("%d", &n);
sz = sqrt(n);
for(int i = 1; i <= n; i++){
scanf("%d%d", &a[i].l, &a[i].r);
a[i].id = i;
}
sort(a + 1, a + 1 + n);
int p = 1, q = 0;
for(int i = 1; i <= n; i++){
int L = a[i].l;
int R = a[i].r;
while(p < L){
del(p, q, 1);
p++;
}
while(p > L){
add(p - 1, q, 1);
p--;
}
while(q < R){
q++;
add(p, q, 0);
}
while(q > R){
del(p, q, 0);
q--;
}
res[a[i].id] = ans;
}
for(int i = 1; i <= n; i++) printf("%lld\n", res[i]);
return 0;
}