Problem B. Harvest of Apples
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2397 Accepted Submission(s): 934
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
Source
2018 Multi-University Training Contest 4
解析 不难发现S(n,m)也满足左上角加右上角(杨辉三角) 所以根据公式可以O(1)得到S(n-1,m),S(n+1,m),S(n,m-1),S(n,m+1) 可以看做区间的转移 从而套用莫队实现求解
AC代码
#include <bits/stdc++.h> #define pb push_back #define mp make_pair #define fi first #define se second #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) #define huan prllf("\n"); #define debug(a,b) cout<<a<<" "<<b<<" "; using namespace std; typedef long long ll; const ll maxn=1e5+10,inf=0x3f3f3f3f; const ll mod=1e9+7; ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;} ll fac[maxn],inv[maxn],ans[maxn]; ll chunk; struct node { ll l,r,id,chunk; }q[maxn]; bool cmp(node a,node b) { if(a.chunk!=b.chunk) return a.l<b.l; return a.r<b.r; } void init() { fac[0]=fac[1]=1; inv[0]=inv[1]=1; for(ll i=2;i<maxn;i++) { fac[i]=fac[i-1]*i%mod; inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod; } for(ll i=2;i<maxn;i++) //不可以写成一个for inv还会用到 inv[i]=inv[i-1]*inv[i]%mod; //可以再开一个数组 写成一个for } ll C(ll x,ll y) { if(y>x) return 0; return fac[x]*inv[y]%mod*inv[x-y]%mod; } int main() { init();//预处理组合数逆元 从而O(1)获得组合数 实现转移 ll t; chunk=sqrt(maxn); scanf("%lld",&t); for(ll i=1;i<=t;i++) { ll n,m; scanf("%lld%lld",&n,&m); q[i]=node{n,m,i,n/chunk+1}; } sort(q+1,q+1+t,cmp); ll l=1,r=0,res=1; for(ll i=1;i<=t;i++) { while(l<q[i].l) { res=(res*2%mod-C(l,r)+mod)%mod; l++; } while(l>q[i].l) { l--; res=(res+C(l,r))%mod*inv[2]%mod; } while(r>q[i].r) { res=(res-C(l,r)+mod)%mod; r--; } while(r<q[i].r) { r++; res=(res+C(l,r))%mod; } ans[q[i].id]=res; } for(ll i=1;i<=t;i++) printf("%lld\n",ans[i]); return 0; }
原文地址:https://www.cnblogs.com/stranger-/p/9414187.html