HDU - 6333:Harvest of Apples (组合数前缀和&莫队)
There are n n apples on a tree, numbered from 1 1 to n n .
Count the number of ways to pick at most m m apples.
Count the number of ways to pick at most m m apples.
InputThe first line of the input contains an integer T T
(1≤T≤10 5 ) (1≤T≤105)
denoting the number of test cases.
Each test case consists of one line with two integers n,m n,m
(1≤m≤n≤10 5 ) (1≤m≤n≤105)
.
OutputFor each test case, print an integer representing the number of ways modulo 10 9 +7 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; }
It is your time to fight!