Advertisement
Guest User

Untitled

a guest
Jan 29th, 2020
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.04 KB | None | 0 0
  1. // #pragma comment(linker, "/stack:200000000")
  2. #pragma GCC optimize("Ofast")
  3. // #pragma GCC option("arch=native","tune=native","no-zero-upper")
  4. // #pragma GCC target("avx")
  5.  
  6. #include <iostream>
  7. #include <vector>
  8. #include <set>
  9. #include <algorithm>
  10. #include <ctime>
  11. #include <cmath>
  12. #include <map>
  13. #include <assert.h>
  14. #include <fstream>
  15. #include <cstdlib>
  16. #include <random>
  17. #include <iomanip>
  18. #include <cstring>
  19. #include <queue>
  20.  
  21. using namespace std;
  22.  
  23. #define sqr(a) ((a)*(a))
  24. #define all(a) (a).begin(), (a).end()
  25.  
  26. const long long MOD = (long long) 1e9 + 7;
  27. const long long MAX_N = (long long) 100;
  28.  
  29. long long binPow(long long a, long long b) {
  30. if (b == 0)
  31. return 1;
  32.  
  33. long long ans = binPow(a, b / 2);
  34. ans = ans * ans % MOD;
  35.  
  36. if (b % 2)
  37. ans = ans * a % MOD;
  38.  
  39. return ans;
  40. }
  41.  
  42. // const int maxn = 5e3 + 5;
  43.  
  44. const int inf = 2e9 + 500;
  45. int dp[(1 << 17) + 100];
  46. bool used[(1 << 17) + 100];
  47.  
  48. int s1, s2;
  49. void trans(int m1, int m2, int& newm, int& newc) {
  50. s1 = 31 - __builtin_clz(m1);
  51. s2 = 31 - __builtin_clz(m2);
  52. if (s1 < s2) {
  53. int dif = s2 - s1;
  54. assert(m1 == (m2 >> dif));
  55. newm = m2 & ((1 << dif) - 1);
  56. newm |= 1 << dif;
  57. newc = dif;
  58. } else {
  59. int dif = s1 - s2;
  60. assert(m2 == (m1 >> dif));
  61. newm = m1 & ((1 << dif) - 1);
  62. newm |= 1 << dif;
  63. newc = 0;
  64. }
  65. }
  66.  
  67.  
  68. const int maxc = 3e6;
  69. vector<int> q[maxc];
  70.  
  71. int main() {
  72. freopen("input.txt", "r", stdin);
  73. ios_base::sync_with_stdio(0);
  74. cin.tie(0);
  75. // srand(time(0));
  76.  
  77. int n;
  78. cin >> n;
  79.  
  80. vector<string> w(n);
  81. vector<int> msk(n, 0);
  82.  
  83. for (int i = 0; i < n; i++) {
  84. cin >> w[i];
  85. }
  86.  
  87. sort(all(w));
  88. for (int i = 0; i < n; i++) {
  89. msk[i] = 1;
  90. for (int j = 0; j < w[i].size(); j++) {
  91. msk[i] *= 2;
  92. msk[i] += w[i][j] - '0';
  93. }
  94. }
  95. for (int i = 0; i < (1 << 17); i++) {
  96. dp[i] = inf;
  97. }
  98.  
  99. for (int i = 0; i < n; i++) {
  100. string word;
  101. {
  102. int m2 = msk[i];
  103. while (m2 > 1) {
  104. word += char(m2 % 2 + '0');
  105. m2 /= 2;
  106. }
  107. reverse(all(word));
  108. }
  109.  
  110. int l = lower_bound(all(w), word) - w.begin();
  111. word += char('1' + 1);
  112.  
  113. int r = upper_bound(all(w), word) - w.begin();
  114. word.pop_back();
  115.  
  116. for (int j = l; j < r; j++) {
  117. if (j != i) {
  118. int start, _;
  119. trans(msk[i], msk[j], start, _);
  120. dp[start] = min(dp[start], max(s1, s2));
  121. }
  122. }
  123. }
  124.  
  125. for (int i = 0; i < (1 << 17); i++) {
  126. if (dp[i] != inf) {
  127. q[dp[i]].push_back(i);
  128. }
  129. }
  130.  
  131. int ans = inf;
  132.  
  133. for (int p = 0; p < maxc; p++) {
  134. for (int iter = 0; iter < q[p].size(); iter++) {
  135. int m = q[p][iter];
  136.  
  137. if (dp[m] != p) {
  138. continue;
  139. }
  140.  
  141. string word;
  142. {
  143. int m2 = m;
  144. while (m2 > 1) {
  145. word += char(m2 % 2 + '0');
  146. m2 /= 2;
  147. }
  148. reverse(all(word));
  149. }
  150.  
  151. int l = lower_bound(all(w), word) - w.begin();
  152. word += char('1' + 1);
  153.  
  154. int r = upper_bound(all(w), word) - w.begin();
  155. word.pop_back();
  156.  
  157. for (int i = l; i < r; i++) {
  158. int newm, newc;
  159.  
  160. trans(m, msk[i], newm, newc);
  161.  
  162. int val = dp[m] + newc;
  163.  
  164. assert(val<maxc);
  165.  
  166. if (newm == 1) {
  167. ans = min(ans, val);
  168. } else {
  169. if (dp[newm] > val) {
  170. // cout << newm << ' ' << val << endl;
  171. dp[newm] = val;
  172. q[val].push_back(newm);
  173. }
  174. }
  175. }
  176.  
  177. {
  178. int m2 = m;
  179. while (m2 > 1) {
  180. int i = lower_bound(all(msk), m2) - msk.begin();
  181. if (i >= msk.size() || msk[i] != m2) {
  182.  
  183. } else {
  184. int newm, newc;
  185.  
  186. trans(m, msk[i], newm, newc);
  187.  
  188. int val = dp[m] + newc;
  189. assert(val<maxc);
  190.  
  191. if (newm == 1) {
  192. ans = min(ans, val);
  193. } else {
  194. if (dp[newm] > val) {
  195. // cout << newm << ' ' << val << endl;
  196. dp[newm] = val;
  197. q[val].push_back(newm);
  198. }
  199. }
  200. }
  201. m2 /= 2;
  202. }
  203. }
  204. }
  205. }
  206. if (ans == inf) {
  207. ans = 0;
  208. }
  209. cout << ans;
  210. return 0;
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement