杭电多校第四场 Problem B. Harvest of Apples(莫队)

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≤mn≤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 
#include 
#include 

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

 

你可能感兴趣的:(ACM-数据结构)