hdu6333 Problem B. Harvest of Apples

题意:一颗树上有n个苹果,求取不大于k个苹果的方案数。
输入:T个案例,输入n,m,n,m<=100000
输出:方案数mod 1000000007

做法:
这里写图片描述

方案数= mi=1C(i,n) ∑ i = 1 m C ( i , n ) ,直接暴力会T,做的时候一直在想数学公式和找规律,没想到用莫队。n,m可以看成r,l,还有区间迁移的时候不是简单的加减,要找到区间转移的变化方程式。

有一点要注意mod要用const定义,不然会T的。

#include"bits/stdc++.h"
using namespace std;
typedef long long ll;
#define N 200000
const int mod=1000000007;
const int MOD = 1000000007;
int fac[N], inv[N];
int powi(int a, int b)
{
    int c = 1;
    for (; b; b >>= 1, a = 1ll * a * a % MOD)
        if (b & 1) c = 1ll * c * a % MOD;
    return c;
}
int C(int a, int b)
{
    return 1ll * fac[a] * inv[b] % MOD * inv[a - b] % MOD;
}
int n,m;

struct node{
    int n,m,id;
}q[100005];
int cmp(node a,node b){
    return a.nint ans[100005];
vectorlst[N];
int in_chunk[100004];
int main(){
    int mx=100000;
    fac[0] = 1; for (int i = 1; i <= mx; ++ i) fac[i] = 1ll * fac[i - 1] * i % MOD;
    inv[mx] = powi(fac[mx], MOD - 2); for (int i = mx - 1; ~i; -- i) inv[i] = 1ll * inv[i + 1] * (i + 1) % MOD;
    int chunk=sqrt(mx);
    int cnt=1;
    for (int i = 1; i <= mx; i += chunk, ++ cnt){
        for (int j = i; j < i + chunk && j <= mx; ++ j)
            in_chunk[j] = cnt;
     //   cout<int T;
    scanf("%d",&T);
    for (int i = 1; i <= T; ++ i)
    {
        scanf("%d%d", &q[i].n, &q[i].m), q[i].id = i;
        lst[in_chunk[q[i].m]].push_back(q[i]);
    }
    for(int i=1;i<=cnt;i++)
    if(lst[i].size())
    {
        sort(lst[i].begin(), lst[i].end(), cmp);
        int sum=0;
        int l=-1,r=lst[i][0].n;
        for(int j=0;jwhile(r%mod;
        while(lm)sum=(sum+C(r,++l))%mod;
        while(l>lst[i][j].m)sum=(sum+mod-C(r,l--))%mod;
        ans[lst[i][j].id]=sum;
    }
    }
    for(int i=1;i<=T;i++){
        printf("%d\n",ans[i]);
    }
    return 0;
}

你可能感兴趣的:(hdu6333 Problem B. Harvest of Apples)