题意:m个猴子分n个桃子要求第一个猴子的桃子最多,问有几种方案
题解:没有想到更好的方法,只能用容斥,枚举第一个猴子的桃子数x,剩下的m-1个猴子分n-x个桃子,要求剩下的每一个猴子的桃子数小于第一个,1个猴子小于方案数-2个猴子小于方案数+。。。
复杂度nlogn
#include <bits/stdc++.h> #define maxn 201000 #define INF 0x3f3f3f3f typedef long long ll; using namespace std; ll a[maxn], b[maxn], mod = 1e9+7; ll power(ll x,ll t,ll mod){ ll ans=1; x %= mod; while(t){ if(t&1) ans = ans*x%mod; x = x*x%mod; t >>= 1; } return ans; } void init(){ a[0] = b[0] = 1; for(ll i=1;i<maxn;i++) a[i] = a[i-1]*i%mod; for(ll i=1;i<maxn;i++) b[i] = power(a[i], mod-2, mod); } ll c(ll n,ll m){ return a[n]*b[m]%mod*b[n-m]%mod; } ll f(ll n,ll m){ return c(n+m-1, n); } int main(){ init(); ll n, m, ans=0, T, temp; scanf("%lld", &T); while(T--){ scanf("%lld%lld", &n, &m); if(n == 1||m == 1){ printf("1 "); continue; } ans = 0; for(int i=1;i<=n;i++){ if((i-1)*(m-1)<n-i) continue; if((n-i)/(m-1)>i) continue; ans += f(n-i, m-1); for(int j=1;n-i*(j+1)>=0;j++){ temp = c(m-1, j)*f(n-i*(j+1), m-1)%mod; if(j%2 == 0) ans = (ans+temp)%mod; else ans = (ans-temp+mod)%mod; } } printf("%lld ", (ans+mod)%mod); } return 0; }