题目链接:奇怪的分组
题目大意:给你一个n和m,然后是m个c[i],要求你将n个数分在m个组里面,第i个组的人数必须大于c[i],问你一共有多少中情况
题目思路:实际上就是从n中分出去sigma(C[i])个数,然后剩下的数假定是sum,则就有sum-1个空,需要插m-1个板子进去,就是高中学的插板法,实际上就是算组合数C(sum-1,m-1,1e9+7),直接套Lucas板子就可以了
#include<bits/stdc++.h> typedef long long LL; using namespace std; const int p = 1e9+7; LL exp_mod(LL a, LL b, LL p) { LL res = 1; while(b != 0) { if(b&1) res = (res * a) % p; a = (a*a) % p; b >>= 1; } return res; } LL Comb(LL a, LL b, LL p) { if(a < b) return 0; if(a == b) return 1; if(b > a - b) b = a - b; LL ans = 1, ca = 1, cb = 1; for(LL i = 0; i < b; ++i) { ca = (ca * (a - i))%p; cb = (cb * (b - i))%p; } ans = (ca*exp_mod(cb, p - 2, p)) % p; return ans; } LL Lucas(int n, int m, int p) { LL ans = 1; while(n&&m&&ans) { ans = (ans*Comb(n%p, m%p, p)) % p; n /= p; m /= p; } return ans; } int main() { int n,m,x; while(~scanf("%d%d",&n,&m)){ LL sum = 0; for(int i = 0;i < m;i++){ scanf("%d",&x); n -= x; } printf("%lld\n", Lucas(n-1,m-1,p)); } return 0; }