題目連接php
容斥+隔板法+Lucas定理c++
#include <bits/stdc++.h> using namespace std; const int N=1e5+10; int n,m,t,mod,ans; int fc[N],fv[N],b[15]; int lucas(int n,int m) { if(m<0||m>n) return 0; if(n<mod&&m<mod) return 1LL*fc[n]*fv[m]*fv[n-m]%mod; return 1LL*lucas(n/mod,m/mod)*lucas(n%mod,m%mod)%mod; } void dfs(int x,int sum,int cnt) { if(sum>m) return; if(x>t) { if(cnt&1) ans=(ans-lucas(m-sum+n,n)+mod)%mod; else ans=(ans+lucas(m-sum+n,n))%mod; return; } dfs(x+1,sum+b[x]+1,cnt+1); dfs(x+1,sum,cnt); } int main() { scanf("%d%d%d%d",&n,&t,&m,&mod); fc[0]=fc[1]=fv[0]=fv[1]=1; for(int i=2; i<mod; ++i) fv[i]=1LL*fv[mod%i]*(mod-mod/i)%mod; for(int i=2; i<mod; ++i) fv[i]=1LL*fv[i-1]*fv[i]%mod,fc[i]=1LL*fc[i-1]*i%mod; for(int i=1; i<=t; ++i) scanf("%lld",b+i); dfs(1,0,0); printf("%lld\n",ans); return 0; }