Artifact Content
Not logged in

Artifact a7ea12621faece166b9ab971f1ed03c96d22059a



//-------------------------------------------------------------
// Modulo Arithmetics
//
// Verified by
//   - TCO10 R3 LV3
//   - SRM 545 Div1 LV2
//   - SRM 554 Div1 LV3
//-------------------------------------------------------------

static const unsigned MODVAL = 1000000007;
struct mint
{
	unsigned val;
	mint():val(0){}
	mint(int      x):val(x%MODVAL) {}
	mint(unsigned x):val(x%MODVAL) {}
	mint(LL       x):val(x%MODVAL) {}
};
mint& operator+=(mint& x, mint y) { return x = x.val+y.val; }
mint& operator-=(mint& x, mint y) { return x = x.val-y.val+MODVAL; }
mint& operator*=(mint& x, mint y) { return x = LL(x.val)*y.val; }
mint operator+(mint x, mint y) { return x+=y; }
mint operator-(mint x, mint y) { return x-=y; }
mint operator*(mint x, mint y) { return x*=y; }

mint POW(mint x, LL e) { mint v=1; for(;e;x*=x,e>>=1) if(e&1) v*=x; return v; }
mint& operator/=(mint& x, mint y) { return x *= POW(y, MODVAL-2); }
mint operator/(mint x, mint y) { return x/=y; }

vector<mint> FAC_(1,1);
mint FAC(LL n) { while( FAC_.size()<=n ) FAC_.push_back( FAC_.back()*LL(FAC_.size()) ); return FAC_[n]; }

// nCk :: O(log MODVAL) time, O(n) space.
mint C(LL n, LL k) { return k<0 || n<k ? 0 : FAC(n) / (FAC(k) * FAC(n-k)); }

// nCk :: O(1) time, O(n^2) space.
vector< vector<mint> > CP_;
mint C(int n, int k) {
	while( CP_.size() <= n ) {
		int nn = CP_.size();
		CP_.push_back(vector<mint>(nn+1,1));
		for(int kk=1; kk<nn; ++kk)
			CP_[nn][kk] = CP_[nn-1][kk-1] + CP_[nn-1][kk];
	}
	return k<0 || n<k ? 0 : CP_[n][k];
}

// O(log MODVAL), MODVAL must be prime: k^b + k^b+1 + ... + k^e
mint GSS(mint k, LL b, LL e) 
{
	if( b > e ) return 0;
	if( k.val <= 1 ) return k*(e-b+1);
	return (POW(k, e+1) - POW(k,b)) / (k-1);
}

// https://en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind
// Number of ways to split |n| labelled objects to exactly |k| unlabbled sets.
//    * If we drop "exactly", the answer was k^n
//    * If we split to "labeled" sets, the answer will be S(n,k)*k!
//    * If unlabeled/unlabeld bar-and-ball-arranging argument.
vector< vector<mint> > SP_;
mint S(int n, int k) {
	while (SP_.size() <= n) {
		int nn = SP_.size();
		SP_.push_back(vector<mint>(nn + 1, 1));
		for (int kk = 2; kk<nn; ++kk)
			SP_[nn][kk] = SP_[nn - 1][kk - 1] + kk*SP_[nn - 1][kk];
	}
	return k<=0 || n<k ? 0 : SP_[n][k];
}