Advertisement
a53

munte2

a53
May 22nd, 2022
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.84 KB | None | 0 0
  1. // Andrei Constantinescu, ETH Zurich
  2. // Linear
  3. #include <algorithm>
  4. #include <bits/stdc++.h>
  5.  
  6. // 6:03
  7. using namespace std;
  8.  
  9. const int MOD = 111181111;
  10.  
  11. namespace gabi {
  12. int CountLinear(const vector<int> &v) {
  13. const int n = v.size();
  14. vector<pair<int, int>> pairs((n + 1) / 2 + 1);
  15. for (int i = 1; i <= n; i++) {
  16. if (i > (n + 1) / 2) {
  17. pairs[n / 2 + 1 - (i - (n + 1) / 2)].second = v[i - 1];
  18. } else {
  19. pairs[i].first = v[i - 1];
  20. }
  21. }
  22. for (int i = 1; i <= n / 2; i++) {
  23. if (pairs[i].first > pairs[i].second) {
  24. swap(pairs[i].first, pairs[i].second);
  25. }
  26. }
  27. sort(pairs.begin() + 1, pairs.begin() + 1 + n / 2);
  28. int ans = 2;
  29. for (int i = 2; i <= n / 2; i++) {
  30. if (pairs[i].first > pairs[i - 1].second) {
  31. ans = (ans * 2) % MOD;
  32. }
  33. }
  34. return ans;
  35. }
  36. } // namespace gabi
  37.  
  38. bool IsMountain(const vector<int> &v) {
  39. if (v[0] == v.size() || v.back() == v.size())
  40. return false;
  41. bool have_more = false;
  42. for (int i = 0; i + 1 < v.size(); ++i) {
  43. if (v[i] < v[i + 1]) {
  44. if (have_more)
  45. return false;
  46. } else {
  47. have_more = true;
  48. }
  49. }
  50. return true;
  51. }
  52.  
  53. // 4: 0 1 2 3
  54. // 5: 0 1 2 3 4
  55. int CountBack(const vector<int> &v) {
  56. const int N = v.size() / 2;
  57. vector<int> perm(N);
  58. int ans = 0;
  59. iota(perm.begin(), perm.end(), 0);
  60. do {
  61. vector<int> t(v.size(), -1);
  62. for (int i = 0; i < N; ++i) {
  63. t[i] = v[perm[i]];
  64. t[v.size() - 1 - i] = v[v.size() - 1 - perm[i]];
  65. }
  66. if (v.size() % 2 == 1) {
  67. t[N] = v[N];
  68. }
  69. for (int mask = 0; mask < (1 << N); ++mask) {
  70. vector<int> t_copy(t);
  71. for (int i = 0; i < N; ++i) {
  72. if (mask & (1 << i)) {
  73. swap(t_copy[i], t_copy[v.size() - 1 - i]);
  74. }
  75. }
  76. ans += IsMountain(t_copy);
  77. }
  78. } while (next_permutation(perm.begin(), perm.end()));
  79. return ans;
  80. }
  81.  
  82. int CountLinear(const vector<int> &v) {
  83. assert(v.size() >= 3);
  84. const int N = v.size() / 2;
  85. vector<pair<int, int>> intervs(N);
  86. for (int i = 0; i < N; ++i) {
  87. const int a = v[i], b = v[v.size() - 1 - i];
  88. if (a < b) {
  89. intervs[i] = {a, b};
  90. } else {
  91. intervs[i] = {b, a};
  92. }
  93. }
  94. sort(intervs.begin(), intervs.end());
  95. if (v.size() % 2 == 1) {
  96. if (v[N] == v.size()) {
  97. // Maximum is in the middle.
  98. if (intervs[N - 1].second != v.size() - 1) {
  99. return 0;
  100. }
  101. } else if (v[N] < intervs[N - 1].first ||
  102. intervs[N - 1].second < v[N]) {
  103. return 0;
  104. }
  105. }
  106. if (intervs[0].second == v.size()) {
  107. return 0;
  108. }
  109. // From now on we can ignore middle.
  110. int maximum = -1, where_max = -1;
  111. for (int i = 0; i < N; ++i) {
  112. if (intervs[i].second > maximum) {
  113. maximum = intervs[i].second, where_max = i;
  114. }
  115. }
  116. int ans = 2;
  117. // To the left of max we need:
  118. // a < c or a < d
  119. // b < d b < c
  120. for (int i = 0; i + 1 <= where_max; ++i) {
  121. const int a = intervs[i].first, b = intervs[i].second;
  122. const int c = intervs[i + 1].first, d = intervs[i + 1].second;
  123. int ways = (a < c && b < d) + (a < d && b < c);
  124. ans = (ways * ans) % MOD;
  125. }
  126. // To the right of max we need a < c < d < b.
  127. for (int i = where_max; i + 1 < N; ++i) {
  128. const int a = intervs[i].first, b = intervs[i].second;
  129. const int c = intervs[i + 1].first, d = intervs[i + 1].second;
  130. if (a > c || b < d)
  131. return 0;
  132. }
  133. return ans;
  134. }
  135.  
  136. void Submit() {
  137. ifstream cin("munte.in");
  138. ofstream cout("munte.out");
  139. int N, C;
  140. cin >> C >> N;
  141. vector<int> v(N);
  142. for (int i = 0; i < N; ++i) {
  143. cin >> v[i];
  144. }
  145. int ans = CountLinear(v);
  146. if (C == 2) {
  147. cout << ans << endl;
  148. } else {
  149. cout << ((ans == 0) ? "NU" : "DA") << endl;
  150. }
  151. }
  152.  
  153. void StressTest() {
  154. for (int N = 3;; ++N) {
  155. cerr << "Attempting N = " << N << endl;
  156. vector<int> perm(N, -1);
  157. iota(perm.begin(), perm.end(), 1);
  158. do {
  159. const int ans = CountBack(perm);
  160. if (ans != CountLinear(perm)) {
  161. for (int i = 0; i < N; ++i) {
  162. cout << perm[i] << ' ';
  163. }
  164. cout << endl;
  165. exit(1);
  166. }
  167. // assert(ans == 0 || ans == gabi::CountLinear(perm));
  168. } while (next_permutation(perm.begin(), perm.end()));
  169. }
  170. }
  171.  
  172. int main() {
  173. // StressTest();
  174. Submit();
  175. return 0;
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement