C++: 累乗、階乗、順列、組み合わせ
これらの計算結果に対するM(通常は10^9付近)の剰余をメモリ上へ格納するクラス。
メモリ使用量が64MB程度以内に収まるよう入力値を制限しているが、取得に関してはチェックしない。
class Power {
public:
Power(int num, int modulus=1000000007) {
if (num > 10000000) { throw std::exception(); }
data_.resize(num + 1);
data_[0] = 1;
for (int i = 1; i <= num; ++i) {
data_[i] = ((long long)num * data_[i - 1]) % modulus;
}
}
int operator()(int n) { return data_[n]; }
private:
std::vector<int> data_;
};
class Factorial {
public:
Factorial(int num, int modulus=1000000007) {
if (num > 10000000) { throw std::exception(); }
data_.resize(num + 1);
data_[0] = 1;
for (long long i = 1; i <= (long long)num; ++i) {
data_[i] = (i * data_[i - 1]) % modulus;
}
}
int operator()(int n) { return data_[n]; }
private:
std::vector<int> data_;
};
class Permutation {
public:
Permutation(int num, int modulus=1000000007) {
if (num > 4000) { throw std::exception(); }
data_.resize(num + 1);
for (int i = 1; i <= num; ++i) {
data_[i].resize(num + 1);
data_[i][0] = 1;
for (int j = 1; j <= i; ++j) {
data_[i][j] = ((long long)(i - j + 1) * data_[i][j - 1]) % modulus;
}
}
}
int operator()(int n, int r) { return data_[n][r]; }
private:
std::vector<std::vector<int> > data_;
};
class Combination {
public:
Combination(int num, int modulus=1000000007) {
if (num > 4000) { throw std::exception(); }
data_.resize(num + 1);
for (int i = 0; i <= num; ++i) {
data_[i].resize(num + 1);
data_[i][0] = 1;
for (int j = 1; j <= i; ++j) {
data_[i][j] =
((long long)data_[i - 1][j] + data_[i - 1][j - 1]) % modulus;
}
}
}
int operator()(int n, int r) { return data_[n][r]; }
private:
std::vector<std::vector<int> > data_;
};