If there is no limit, the answer is directly with the partition method C (m-1,n-1)
For >=x limit, we directly in the corresponding position first put x-1 can, namely m=m-(X-1)
For <=x restrictions, we can use the repulsion principle to convert it to the limit of the >=x above.
That is, minus 1 unsatisfied plus 2 unsatisfied minus 3 unsatisfied .....
After that is the calculation of the combinatorial number, for a very large modulus, we can only decompose it, then the CRT restore can
But we may not have an inverse, the data range does not allow us to recursively calculate the number of combinations
We know that there is no inverse and only if (A,P) is not a mutual element, we can divide the factorial into two parts: the mutual element and the non-reciprocity
The part of the element has a cyclic section, and we can quickly power after the violent calculation of the cyclic section.
The parts of the GCD we can propose their own and record the index, the remainder becomes the computational factorial, recursion can
#include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> #include < Algorithm>using namespace Std; const int Maxn=110;typedef long long ll;int t,tot=0; LL p,n,n1,n2,m; LL MOD[MAXN],PRIME[MAXN],A[MAXN]; LL NUM[MAXN]; LL x,y,d; LL ans; void Get_mod (LL x) {for (int i=2;i*i<=x;++i) {if (x%i==0) {prime[++tot]=i;mod[tot]=1; while (x%i==0) {x/=i;mod[tot]*=i;} }} if (x>1) prime[++tot]=x,mod[tot]=x;} void Ex_gcd (LL a,ll b,ll &x,ll &y,ll &d) {if (b==0) {x=1;y=0;d=a;} ELSE{EX_GCD (b,a%b,y,x,d); y-= (A/b) *x;}} ll Pow_mod (ll v,ll p,ll MoD) {ll tmp=1; while (p) {if (p&1) Tmp=tmp*v%mod; v=v*v%mod;p>>=1; }return tmp;} LL INV (ll A,ll b) {ex_gcd (a,b,x,y,d); Return (X%B+B)%b;} ll CRT () {ll ans=0; for (int i=1;i<=tot;++i) {LL m=p/mod[i]; EX_GCD (MOD[I],M,D,Y,D); Ans= (Ans+y*m*a[i])%p; }return (Ans+p)%p;} pair<ll,ll> FAC (int k,ll N) {if (n==0) RetuRN Make_pair (0,1); int x=n/prime[k],y=n/mod[k]; LL Ans=1; if (y) {for (int i=2;i<mod[k];++i) if (i%prime[k]!=0) ans= (ans*1ll*i)%mod[k]; Ans=pow_mod (Ans,y,mod[k]); } for (int i=y*mod[k]+1;i<=n;++i) if (i%prime[k]!=0) ans= (ans*1ll*i)%mod[k]; Pair<ll,ll> TMP=FAC (k,x); Return Make_pair (X+tmp.first,ans*tmp.second%mod[k]);} LL cal (int k,ll n,ll m) {if (n<m) return 0; Pair<ll,ll> A=FAC (K,n), B=FAC (k,m), C=FAC (K,N-M); Return Pow_mod (Prime[k],a.first-b.first-c.first,mod[k]) *a.second%mod[k] *INV (B.second,mod[k])%MOD[K]*INV ( C.SECOND,MOD[K])%mod[k];} ll C (ll n,ll m) {for (int i=1;i<=tot;++i) a[i]=cal (i,n,m); return CRT ();} void DFS (int pos,int now,ll sum) {if (pos>n1) {if (now) ans-=c (m-1-sum,n-1); else Ans+=c (m-1-sum,n-1); Ans= (ans+p)%p; Return } DFS (Pos+1,now,sum); DFS (Pos+1,now^1,sum+num[pos]);} int main () {scanf ("%d%lld", &t,&p); Get_mod (P); while (t--) {scanf ("%lld%lld%lld%lld ", &n,&n1,&n2,&m); for (int i=1;i<=n1;++i) scanf ("%lld", &num[i]); for (int i=1;i<=n2;++i) {scanf ("%lld", &x); m=m-x+1;} ans=0; DFS (1,0,0); printf ("%lld\n", (ans+p)%p); }return 0;}
Bzoj 3129 SDOI2013 equation