Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1463 Accepted Submission(s): 555ios
Problem Descriptionapp
There are n apples on a tree, numbered from 1 to n.
Count the number of ways to pick at most m apples.spa
Input.net
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).code
Outputblog
For each test case, print an integer representing the number of ways modulo 109+7.ip
Sample Inputget
2 input
5 2 string
1000 500
Sample Output
16
924129523
題意:計算c(n,0),c(n,1),,,c(n,m);
思路:分塊,將1e5分紅根號1e5塊(333)。採用逆元的方式計算出n爲333倍數的全部組合數,在處理出其前綴,另外處理處n<333的全部組合數,這樣對於n<333的狀況直接處理便可,對於n>=333狀況,分爲兩部分一部分爲333的倍數p,另外一部分爲除以333的餘數q,這樣就能夠轉換爲在這兩部份內分別處理。總時間複雜度爲O(333*T)。
參考自:https://blog.csdn.net/zstu_zy/article/details/81334302
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<vector> using namespace std; typedef long long ll; const ll mod = 1e9+7; const int maxn = 1e5+10; ll dp[335][maxn],C[335][335]; ll inv[maxn],fac[maxn],invf[maxn]; void init() { inv[1]=1; for (int i=2;i<maxn;i++) inv[i]=((mod-mod/i)*inv[mod%i])%mod; fac[0] = 1; for(int i = 1;i<maxn;i++) fac[i] = (fac[i-1] * (ll)i)%mod; invf[0] = 1; for(int i = 1;i<maxn;i++) invf[i] = (invf[i-1]*inv[i])%mod; C[0][0] = 1; for(int i=1;i<335;i++) { C[i][0] = 1; for(int j=1;j<=i;j++) C[i][j] = (C[i-1][j]+C[i-1][j-1])%mod; } dp[0][0] = 1; for(int i=1;i*333<maxn;i++) { for(int j=0;j<=i*333;j++) { dp[i][j] = ((fac[i*333]*invf[j])%mod*invf[i*333-j])%mod; if(j>0)dp[i][j] = (dp[i][j] + dp[i][j-1])%mod; } } } int main() { init(); int t; int n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int p = n/333,q = n%333; ll ans = 0; if(n<=333) { for(int i = 0;i <= m;i++)ans = (ans + C[n][i])%mod; printf("%lld\n",ans); } else { for(int i =0;i<=min(q,m);i++) { ans = (ans + (C[q][i]*dp[p][min(m-i,p*333)])%mod)%mod; } printf("%lld\n",ans); } } }