Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstring>
- #include <cassert>
- #include <iostream>
- #include <algorithm>
- #include <vector>
- #include <set>
- #define FOR(i, a, b) for (int i = (a); i < (b); ++i)
- #define REP(i, n) FOR (i, 0, n)
- #define _ << " _ " <<
- #define TRACE(x) cerr << #x << " = " << x << endl
- #define debug(...) fprintf(stderr, __VA_ARGS__)
- //#define debug
- //#define TRACE(x)
- using namespace std;
- typedef long long llint;
- const int MAXN = 10000010;
- const int A = 1103515245;
- const int B = 12345;
- const int M = (1LL<<31) - 1;
- int n, r;
- int a[2*MAXN];
- llint ans[2*MAXN];
- pair<llint, int> U[2*MAXN], D[2*MAXN];
- int p10[60];
- llint get(pair<llint, int> up, int ud,
- pair<llint, int> dp, int dd) {
- if (ud == -1 && dd == -1) return 0;
- if (ud == -1) return dd * p10[dp.second] + dp.first;
- if (dd == -1) return up.first*10 + ud;
- return (up.first*10 + ud) * p10[1 + dp.second] +
- dd * p10[dp.second] + dp.first;
- }
- int main(void) {
- memset(a, -1, sizeof a);
- scanf("%d%d", &n, &r);
- for (int i = 2; i <= n; ++i) {
- r = ((llint)A*r + B) & M;
- a[i] = ((r >> 16) % 9) + 1;
- }
- p10[0] = 1;
- for (int i = 1; i < 60; ++i)
- p10[i] = 10 * p10[i-1];
- llint sum = 0;
- for (int i = n; i >= 1; --i) {
- if (i > 1) {
- pair<llint, int> tmp;
- tmp = {U[i].first * 10 + a[i], 1+U[i].second};
- if (U[i/2] < tmp) U[i/2] = tmp;
- tmp = {D[i].first + a[i] * p10[U[i].second], 1+U[i].second};
- if (D[i/2] < tmp) D[i/2] = tmp;
- }
- ans[i] = max(ans[i], get(U[2*i], a[2*i], D[2*i+1], a[2*i+1]));
- ans[i] = max(ans[i], get(U[2*i+1], a[2*i+1], D[2*i], a[2*i]));
- if (!(ans[i] >= 0 && ans[i] < 10133099161583616LL)) {
- TRACE(i _ ans[i]);
- }
- sum += ans[i];
- }
- TRACE(ans[1]);
- printf("%lld\n", sum);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement