1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| #include <bits/stdc++.h>
typedef long long ll;
const int N = 125;
int lg2(ll n) { return 63 - __builtin_clzll(n); } int f(ll n, int l, int r, int now); int g(ll n, int l, int r, int now); void inc(int &a, int b); void dec(int &a, int b);
int _f[N][60][60], _g[N][60][60]; std::map<ll, int> mp; int tot; int pw2[120]; ll n; int Mod;
int main() { scanf("%lld %d", &n, &Mod); pw2[0] = 1; for (int i = 1; i < 120; ++i) pw2[i] = (pw2[i - 1] << 1) % Mod; for (int i = 1; i <= 120; ++i) { for (int j = 0; j < 60; ++j) { for (int k = 0; k < 60; ++k) { _f[i][j][k] = _g[i][j][k] = -1; } } } mp[n] = tot = 1; int ans = (n + 1) % Mod; for (int i = 0; i < 60; ++i) { for (int j = 0; j < 60; ++j) { ans = (ans + f(n, i, j, 1)) % Mod; } } printf("%d\n", ans); return 0; }
void inc(int &a, int b) { (a += b) >= Mod ? a -= Mod : a; } void dec(int &a, int b) { (a -= b) < 0 ? a += Mod : a; }
int f(ll n, int l, int r, int now) { if (n == 0) return 0; if ((1ll << std::max(l, r)) > n) return 0; if (_f[now][l][r] != -1) return _f[now][l][r]; int w = lg2(n); ll L = (1ll << w) - 1, R = n - (1ll << w); if (!mp.count(L)) mp[L] = ++tot; if (!mp.count(R)) mp[R] = ++tot; int nL = mp[L], nR = mp[R]; int ans = (f(L, l, r, nL) + f(R, l, r, nR)) % Mod; if (l == w && r == w) inc(ans, 1ll * pw2[w] * ((R + 1) % Mod) % Mod); if (l == w) { for (int d = 0; d < w; ++d) inc(ans, 1ll * pw2[w] * f(R, d, r, nR) % Mod); } if (r == w) { for (int d = 0; d < w; ++d) inc(ans, 1ll * f(L, l, d, nL) * ((R + 1) % Mod) % Mod); } int s1 = 0; for (int d1 = 0; d1 < w; ++d1) inc(s1, f(L, l, d1, nL)); int s2 = 0; for (int d2 = 0; d2 < w; ++d2) inc(s2, f(R, d2, r, nR)); inc(ans, 1ll * s1 * s2 % Mod); for (int d = 0; d < w; ++d) { dec(ans, 1ll * f(L, l, d, nL) * f(R, d, r, nR) % Mod); inc(ans, 1ll * g(L, l, d, nL) * f(R, d, r, nR) % Mod * (pw2[d] - 1) % Mod); } return _f[now][l][r] = ans; } int g(ll n, int l, int r, int now) { if (n == 0) return 0; if ((1ll << std::max(l, r)) > n) return 0; if (_g[now][l][r] != -1) return _g[now][l][r]; int w = lg2(n); ll L = (1ll << w) - 1, R = n - (1ll << w); if (!mp.count(L)) mp[L] = ++tot; if (!mp.count(R)) mp[R] = ++tot; int nL = mp[L], nR = mp[R]; int ans = (g(L, l, r, nL) + g(R, l, r, nR)) % Mod; if (l == w && r == w) inc(ans, pw2[w]); if (l == w) { for (int d = 0; d < w; ++d) inc(ans, 1ll * pw2[w] * g(R, d, r, nR) % Mod); } if (r == w) { for (int d = 0; d < w; ++d) inc(ans, 1ll * f(L, l, d, nL) * (((R + 1) >> w) % Mod) % Mod); } int s1 = 0; for (int d1 = 0; d1 < w; ++d1) inc(s1, f(L, l, d1, nL)); int s2 = 0; for (int d2 = 0; d2 < w; ++d2) inc(s2, g(R, d2, r, nR)); inc(ans, 1ll * s1 * s2 % Mod); for (int d = 0; d < w; ++d) { dec(ans, 1ll * f(L, l, d, nL) * g(R, d, r, nR) % Mod); inc(ans, 1ll * g(L, l, d, nL) * g(R, d, r, nR) % Mod * (pw2[d] - 1) % Mod); } return _g[now][l][r] = ans; }
|