#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
using i32 = int;
template<typename T> T load() { T x; cin >> x; return x; }
template<typename T> vector<T> loadN(int s) { vector<T> vt(s); for(auto& el : vt) el = load<T>(); return vt; }
template<typename T> ostream& operator<<(ostream& os, const vector<T>& vt) { for(auto& el : vt) os << el << ' '; return os; }
template<typename T> T fastPow(T x, i32 W) { if(W == 0) return T(1); return fastPow(x * x, W / 2) * (W & 1 ? x : T(1)); }
struct Hash {
Hash(i32 val = 0):val(val % MOD) {}
Hash(i64 val):val(val % LMOD) {}
Hash operator+(const Hash& el) const { return Hash(*this) += el; }
Hash operator*(const Hash& el) const { return Hash(*this) *= el; }
Hash operator+=(const Hash& el) { val += el.val; val %= MOD; return *this; }
Hash operator*=(const Hash& el) { val = (1ll * val * el.val) % LMOD; return *this; }
Hash inv() const { return fastPow(*this, MOD - 2); }
Hash operator/(const Hash& el) const { return *this * el.inv(); }
static void mutate(i32 val) { LMOD = MOD = val; }
friend ostream& operator<<(ostream& os, const Hash& el) { return os << el.val; }
static i32 MOD;
static i64 LMOD;
i32 val;
};
i64 Hash::LMOD = 0;
i32 Hash::MOD = 0;
struct Calculator {
Calculator(i32 size):fact(size + 1), inv(size + 1) {
fact[0] = 1;
for(i32 i = 1 ; i <= size ; ++i) fact[i] = fact[i - 1] * i;
inv[size] = fact[size].inv();
for(i32 i = size - 1 ; i >= 0 ; --i) inv[i] = inv[i + 1] * (i + 1);
}
Hash choose(i32 k, i32 n) const { return fact[n] * inv[k] * inv[n - k];}
Hash factorial(i32 n) const { return fact[n]; }
vector<Hash> fact;
vector<Hash> inv;
};
bool checkLifeTime(list<i32>&& world, i32 desire, i32 size) {
while(desire --> 0) {
if(size <= 1) return false;
auto it = world.begin();
auto previous = -1;
while(it != world.end()) {
auto future = next(it);
auto surrounding = max(previous, (future == world.end() ? -1 : *future));
previous = *it;
if(*it < surrounding) {
world.erase(it);
--size;
}
it = future;
}
}
if(size != 1) return false;
return true;
}
i32 main() {
ios::sync_with_stdio(false);
auto seqSize = load<i32>();
auto lifeTime = load<i32>();
Hash::mutate(load<i32>());
//auto calc = Calculator(seqSize);
auto all = vector<i32>(seqSize);
iota(all.begin(), all.end(), 1);
if(lifeTime > ceil(log2(seqSize)) + 1) {
cout << "0\n";
return 0;
}
auto result = Hash(0);
do {
auto curr = list<i32>(all.begin(), all.end());
if(checkLifeTime(move(curr), lifeTime, seqSize))
result += 1;
} while(next_permutation(all.begin(), all.end()));
cout << result << '\n';
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include<bits/stdc++.h> using namespace std; using i64 = long long; using i32 = int; template<typename T> T load() { T x; cin >> x; return x; } template<typename T> vector<T> loadN(int s) { vector<T> vt(s); for(auto& el : vt) el = load<T>(); return vt; } template<typename T> ostream& operator<<(ostream& os, const vector<T>& vt) { for(auto& el : vt) os << el << ' '; return os; } template<typename T> T fastPow(T x, i32 W) { if(W == 0) return T(1); return fastPow(x * x, W / 2) * (W & 1 ? x : T(1)); } struct Hash { Hash(i32 val = 0):val(val % MOD) {} Hash(i64 val):val(val % LMOD) {} Hash operator+(const Hash& el) const { return Hash(*this) += el; } Hash operator*(const Hash& el) const { return Hash(*this) *= el; } Hash operator+=(const Hash& el) { val += el.val; val %= MOD; return *this; } Hash operator*=(const Hash& el) { val = (1ll * val * el.val) % LMOD; return *this; } Hash inv() const { return fastPow(*this, MOD - 2); } Hash operator/(const Hash& el) const { return *this * el.inv(); } static void mutate(i32 val) { LMOD = MOD = val; } friend ostream& operator<<(ostream& os, const Hash& el) { return os << el.val; } static i32 MOD; static i64 LMOD; i32 val; }; i64 Hash::LMOD = 0; i32 Hash::MOD = 0; struct Calculator { Calculator(i32 size):fact(size + 1), inv(size + 1) { fact[0] = 1; for(i32 i = 1 ; i <= size ; ++i) fact[i] = fact[i - 1] * i; inv[size] = fact[size].inv(); for(i32 i = size - 1 ; i >= 0 ; --i) inv[i] = inv[i + 1] * (i + 1); } Hash choose(i32 k, i32 n) const { return fact[n] * inv[k] * inv[n - k];} Hash factorial(i32 n) const { return fact[n]; } vector<Hash> fact; vector<Hash> inv; }; bool checkLifeTime(list<i32>&& world, i32 desire, i32 size) { while(desire --> 0) { if(size <= 1) return false; auto it = world.begin(); auto previous = -1; while(it != world.end()) { auto future = next(it); auto surrounding = max(previous, (future == world.end() ? -1 : *future)); previous = *it; if(*it < surrounding) { world.erase(it); --size; } it = future; } } if(size != 1) return false; return true; } i32 main() { ios::sync_with_stdio(false); auto seqSize = load<i32>(); auto lifeTime = load<i32>(); Hash::mutate(load<i32>()); //auto calc = Calculator(seqSize); auto all = vector<i32>(seqSize); iota(all.begin(), all.end(), 1); if(lifeTime > ceil(log2(seqSize)) + 1) { cout << "0\n"; return 0; } auto result = Hash(0); do { auto curr = list<i32>(all.begin(), all.end()); if(checkLifeTime(move(curr), lifeTime, seqSize)) result += 1; } while(next_permutation(all.begin(), all.end())); cout << result << '\n'; } |
English