Description

Calculate:

x=0NCNxxk
  • 1N109,1k5000

Prefix Knowledge

  • Sterling numbers the second kind

    Sterling numbers the second kind, which is written in S(n,k), is defined as the number of ways to put n different balls into k same boxes.

    It can be calculated as below:

    S(1,1)=1S(n,k)=S(n1,k1)+nS(n1,k)

Solution

Use Stirling numbers the second kind to change the form of xk

We have:

xk=i=0xCxii!S(k,i)

Proof:

Let's consider a problem: What's the number of ways to put k different balls into x different boxes.

Obviously the answer is xk.

In another way, we may index i that represents the number of boxes that have balls in, then the ways in this case is S(k,i). And because the boxes are different , we should multiply i!

Thus, the answer is also i=0xCxii!S(k,i)

So now we have xk=i=0xCxii!S(k,i)

Then we have:

Ans=x=0NCNxxk=x=0NCNxi=0xCxii!S(k,i)=x=0Ni=0xCNxCxii!S(k,i)=i=0Nx=iNCNxCxii!S(k,i)=i=0NS(k,i)x=iNCNxCxii!

Then change the form of x[i,n]CNxCxii!

Notice that this is the answer to the problem:

What's the number of ways to choose x objects(same) from N, then i (different) from k ?

We may first index i, then consist the other Ni. They can be either chosen or not during the first round.

Thus we have $\sum {x\in[i,N]}C {N}^x\cdot C x^i\cdot i!=A {N}^i\cdot 2^{N-i}$

After,

Ans=i=0NS(k,i)x=iNCNxCxii!=i=0NS(k,i)ANi2Ni

We may notice that when ik,  S(k,i)=0, so we just need to index i from 0 to k, not to N

Thus, the problem can be solved in O(k2)

Code

const int N = 5005;
const int MOD = 1e9+7;
int s[N][N];
int n, k;
int power(int base, int exp) {
   if (exp < 0) return 0;
   int res=1;
   while (exp) {
       if (exp&1) (res*=base)%=MOD;
       (base*=base) %= MOD; exp >>=1; }
   return res; }
int inv(int u) { return power(u,MOD-2); }
int nAr(int n, int r) {
   int res=1;
   rep (i,r) (res*=(n-i)) %=MOD;
   return res; }
void initStirling() {
   s[1][1] = 1;
   repi (i,2,N-1) repa (j,i) s[i][j] = (s[i-1][j-1] + s[i-1][j]*j) % MOD; }
void init() {
   scanf(II,&n,&k); 
   initStirling();
}
void solve() {
   int ans=0;
   rep (j,k+1) { 
       (ans+= nAr(n,j) * power(2,n-j) % MOD * s[k][j] % MOD) %= MOD; }
   printf(IN,ans);
}



Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.