EntropyIncreaser

Untitled

Nov 30th, 2019
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.19 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define LOG(FMT...) fprintf(stderr, FMT)
  4.  
  5. using namespace std;
  6.  
  7. typedef long long ll;
  8. typedef unsigned long long ull;
  9. typedef vector<int> vi;
  10.  
  11. // mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  12.  
  13. template<class T>
  14. istream &operator>>(istream &is, vector<T> &v) {
  15. for (T &x : v)
  16. is >> x;
  17. return is;
  18. }
  19.  
  20. ostream &operator<<(ostream &os, const pair<char, int> &unit) {
  21. return os << unit.first << "^" << unit.second;
  22. }
  23.  
  24. template<class T>
  25. ostream &operator<<(ostream &os, const vector<T> &v) {
  26. if (!v.empty()) {
  27. os << v.front();
  28. for (int i = 1; i < v.size(); ++i)
  29. os << ' ' << v[i];
  30. }
  31. return os;
  32. }
  33.  
  34. const int N = 110;
  35.  
  36. int P;
  37. int fac[N], ifac[N], pw[N][N * N];
  38.  
  39. int mpow(int x, int k) {
  40. int ret = 1;
  41. while (k) {
  42. if (k & 1)
  43. ret = ret * (ll) x % P;
  44. k >>= 1;
  45. x = x * (ll) x % P;
  46. }
  47. return ret;
  48. }
  49.  
  50. int norm(int x) { return x >= P ? x - P : x; }
  51.  
  52. void add(int &x, int y) {
  53. if ((x += y) >= P)
  54. x -= P;
  55. }
  56.  
  57. void sub(int &x, int y) {
  58. if ((x -= y) < 0)
  59. x += P;
  60. }
  61.  
  62. void exGcd(int a, int b, int &x, int &y) {
  63. if (!b) {
  64. x = 1;
  65. y = 0;
  66. return;
  67. }
  68. exGcd(b, a % b, y, x);
  69. y -= a / b * x;
  70. }
  71.  
  72. int inv(int a) {
  73. int x, y;
  74. exGcd(a, P, x, y);
  75. return norm(x + P);
  76. }
  77.  
  78. void prepare(int n, int k) {
  79. fac[0] = 1;
  80. for (int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * (ll) i % P;
  81. ifac[1] = 1;
  82. for (int i = 2; i <= n; ++i)
  83. ifac[i] = -(P / i) * (ll) ifac[P % i] % P + P;
  84. ifac[0] = 1;
  85. for (int i = 1; i <= n; ++i)
  86. ifac[i] = ifac[i - 1] * (ll) ifac[i] % P;
  87. for (int i = 0; i <= k; ++i) {
  88. pw[i][0] = 1;
  89. for (int j = 1; j <= n * n; ++j)
  90. pw[i][j] = pw[i][j - 1] * (ll) i % P;
  91. }
  92. }
  93.  
  94. int f[N][N], g[N][N];
  95.  
  96. int main() {
  97. #ifdef LBT
  98. freopen("test.in", "r", stdin);
  99. int nol_cl = clock();
  100. #endif
  101. ios::sync_with_stdio(false);
  102. cin.tie(nullptr);
  103.  
  104. int n, m, k;
  105. cin >> n >> m >> k >> P;
  106. prepare(max(n, m), k);
  107. f[0][0] = 1;
  108. for (int i = 1; i <= k; ++i) {
  109. for (int a = 0; a <= n; ++a)
  110. for (int b = 0; b <= m; ++b) {
  111. int v = f[a][b] * (ll) mpow(i, P - 1 - a * m - b * n + a * b) % P * fac[n - a] % P * fac[m - b] % P;
  112. for (int c = a; c <= n; ++c)
  113. for (int d = b; d <= m; ++d)
  114. for (int j = 0; j <= c - a; ++j)
  115. for (int l = 0; l <= d - b; ++l)
  116. add(g[c][d],
  117. mpow(P - 1, j + l) * (ll) ifac[j] % P * ifac[l] % P * ifac[c - a - j] % P * ifac[d - b - l] % P
  118. * mpow(k - i + 1, (c - j) * (d - l) - a * b) % P * mpow(k - i, c * l + d * j - j * l) % P * v
  119. % P);
  120. }
  121. for (int c = 0; c <= n; ++c)
  122. for (int d = 0; d <= m; ++d)
  123. g[c][d] = g[c][d] * (ll) mpow(i, c * m + d * n - c * d) % P * ifac[n - c] % P * ifac[m - d] % P;
  124. memcpy(f, g, sizeof(f));
  125. for (int c = 0; c <= n; ++c)
  126. cerr << vector<int>(g[c], g[c] + m + 1) << '\n';
  127. cerr << "-----------------\n";
  128. memset(g, 0, sizeof(g));
  129. }
  130. cout << f[n][m];
  131.  
  132. #ifdef LBT
  133. LOG("Time: %dms\n", int ((clock()
  134. -nol_cl) / (double)CLOCKS_PER_SEC * 1000));
  135. #endif
  136. return 0;
  137. }
Advertisement
Add Comment
Please, Sign In to add comment