Live2d Test Env

HDU - 6333:Harvest of Apples (组合数前缀和&莫队)

There are n apples on a tree, numbered from 1 to n .
Count the number of ways to pick at most m apples.

InputThe first line of the input contains an integer T (1T10 (1≤T≤105) denoting the number of test cases.
Each test case consists of one line with two integers n,n,m (1mn10 (1≤m≤n≤105) .
OutputFor each test case, print an integer representing the number of ways modulo 10 +109+7 .Sample Input

2
5 2
1000 500

Sample Output

16
924129523

题意:T组询问,每次给出N, M,求C(N,0)+C(N,1)+...C(N,M);

思路:前缀和没有什么特别的公式, 所以我们考虑询问之间的关系:

      易得,F(N,M)=F(N,M-1)+C(N,M);

      由杨辉三角,可得, F(N,M)=2*F(N-1,M)-C(N-1,M);

然后就可以跑莫队了.

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=100010;
const int Mod=1e9+7;
int f[maxn],rev[maxn],ans[maxn],B;
struct in{ int l,r,id,g; }s[maxn];
bool cmp(in w,in v){ if(w.g==v.g) return w.r<v.r; return w.g<v.g ;}
int qpow(int a,int x){
    int res=1; while(x){
        if(x&1) res=(ll) res*a%Mod;
        a=(ll)a*a%Mod; x>>=1;
    } return res;
}
void prepare()
{
    f[0]=rev[0]=1;
    rep(i,1,maxn-10) f[i]=(ll)f[i-1]*i%Mod;
    rev[100000]=qpow(f[100000],Mod-2);
    for(int i=maxn-11;i>=1;i--) rev[i]=(ll)rev[i+1]*(i+1)%Mod;
}
int C(int n,int m){
    if(n<m) return 0;
    return (ll)f[n]*rev[n-m]%Mod*rev[m]%Mod;
}
int main()
{
    prepare(); B=sqrt(100000);
    int N; scanf("%d",&N);
    rep(i,1,N) scanf("%d%d",&s[i].l,&s[i].r),s[i].id=i,s[i].g=s[i].l/B;
    sort(s+1,s+N+1,cmp);
    int L=1,R=1,res=2;
    rep(i,1,N){
        while(L<s[i].l) res=((2*res-C(L++,R))%Mod+Mod)%Mod;
        while(L>s[i].l) res=(ll)(res+C(--L,R))%Mod*rev[2]%Mod;
        while(R<s[i].r) res=(res+C(L,++R))%Mod;
        while(R>s[i].r) res=(res-C(L,R--)+Mod)%Mod;
        ans[s[i].id]=res;
    }
    rep(i,1,N) printf("%d\n",ans[i]);
    return 0;
}

 

posted @ 2018-10-23 17:00  nimphy  阅读(480)  评论(0编辑  收藏  举报