Advertisement
Guest User

Untitled

a guest
Apr 30th, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.17 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cassert>
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <set>
  8.  
  9. #include <tuple>
  10.  
  11. #define FOR(i, a, b) for (int i = (a); i < (b); ++i)
  12. #define REP(i, n) FOR (i, 0, n)
  13. #define _ << " _ " <<
  14. #define TRACE(x) cerr << #x << " = " << x << endl
  15. #define debug(...) fprintf(stderr, __VA_ARGS__)
  16. //#define debug
  17. //#define TRACE(x)
  18.  
  19. using namespace std;
  20.  
  21. typedef long long llint;
  22.  
  23. const int MAXN = 10000010;
  24.  
  25. const int A = 1103515245;
  26. const int B = 12345;
  27. const int M = (1LL<<31) - 1;
  28.  
  29. int n, r;
  30. int a[MAXN];
  31. // string ans[MAXN];
  32. // string U[2*MAXN], D[2*MAXN];
  33. llint sum[110];
  34. __int128 p10[110];
  35. __int128 S;
  36.  
  37. inline bool cmp(const string &s1, const string &s2) {
  38. if (s1.size() != s2.size()) return s1.size() < s2.size();
  39. return s1 < s2;
  40. }
  41.  
  42. inline string merge(__int128 U, __int128 D) {
  43. string s1, s2;
  44. while (U) { s1.push_back(char(U % 10 + '0')); U /= 10; }
  45. reverse(s1.begin(), s1.end());
  46. while (D) { s2.push_back(char(D % 10 + '0')); D /= 10; }
  47. reverse(s2.begin(), s2.end());
  48. return s1 + s2;
  49. }
  50.  
  51. inline string max_num(const string &s1, const string &s2) {
  52. return cmp(s1, s2) ? s2 : s1;
  53. }
  54.  
  55. inline int len(__int128 x) {
  56. int ret = 0;
  57. while (x) { x /= 10; ++ret; }
  58. return ret;
  59. }
  60.  
  61. tuple<__int128, __int128, int> solve(int u) {
  62. if (u > n) return make_tuple(0, 0, -1);
  63. __int128 U1, U2, D1, D2;
  64. int L1, L2, L;
  65. __int128 U, D;
  66. if (2*u <= n) {
  67. tie(U1, D1, L1) = solve(2*u);
  68. tie(U2, D2, L2) = solve(2*u+1);
  69.  
  70. if (u < 1000) {
  71. string ans = max_num(merge(U1, D2), merge(U2, D1));
  72. int sz = int(ans.size());
  73. REP (j, sz) sum[j] += ans[sz-j-1]-'0';
  74. } else {
  75. __int128 ans, tmp1, tmp2;
  76. tmp1 = U1 * p10[L2 + 1] + D2;
  77. tmp2 = U2 * p10[L1 + 1] + D1;
  78. ans = max(tmp1, tmp2);
  79. S += ans;
  80. }
  81. U = max(U1, U2);
  82. if (D1 > D2) { D = D1, L = L1; } else { D = D2, L = L2; }
  83. } else {
  84. U = D = 0;
  85. L = -1;
  86. }
  87. U = U * 10 + a[u];
  88. D = a[u] * p10[L + 1] + D;
  89. // U.push_back(char(a[u]+'0'));
  90. // D.insert(0, 1, char(a[u]+'0'));
  91. return make_tuple(U, D, L + 1);
  92. }
  93.  
  94. int main(void) {
  95. memset(a, -1, sizeof a);
  96.  
  97. scanf("%d%d", &n, &r);
  98. for (int i = 2; i <= n; ++i) {
  99. r = ((llint)A*r + B) & M;
  100. a[i] = ((r >> 16) % 9) + 1;
  101. }
  102.  
  103. p10[0] = 1;
  104. FOR (i, 1, 61) p10[i] = 10 * p10[i-1];
  105.  
  106. // for (int i = n; i >= 1; --i) {
  107. // ans[i] = max_num(U[2*i] + D[2*i+1], U[2*i+1] + D[2*i]);
  108. // int sz = int(ans[i].size());
  109. // for (int j = 0; j < sz; ++j)
  110. // sum[j] += ans[i][sz-j-1]-'0';
  111.  
  112. // if (i == 1) break;
  113. // U[i].push_back(char(a[i] + '0'));
  114. // D[i].insert(0, 1, char(a[i] + '0'));
  115. // U[i/2] = max_num(U[i/2], U[i]);
  116. // D[i/2] = max_num(D[i/2], D[i]);
  117. // }
  118.  
  119. solve(1);
  120. __int128 tmp = 0;
  121. REP (i, 100) {
  122. tmp += sum[i];
  123. sum[i] = llint(tmp % 10);
  124. tmp /= 10;
  125. }
  126.  
  127. tmp = S;
  128. for (int i = 0; i < 101; ++i) {
  129. tmp += sum[i];
  130. sum[i] = llint(tmp % 10);
  131. tmp /= 10;
  132. }
  133.  
  134. int start = -1;
  135. for (int i = 101; i >= 0; --i)
  136. if (sum[i] != 0) {
  137. start = i;
  138. break;
  139. }
  140.  
  141. if (start == -1) {
  142. printf("0\n");
  143. } else {
  144. for (int i = start; i >= 0; --i)
  145. printf("%lld", sum[i]);
  146. printf("\n");
  147. }
  148.  
  149. return 0;
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement