写了个记忆化搜索。
Code
#include <iostream>
#include <string.h>
#define int long long
using namespace std;
const int N = 64, mod = 998244353;
int dp[N][10][10][10][2][2][2][2][2][2], n, a1, a2, a3, a[N];
int rd() {
int res = 0; bool f = 0; char ch = getchar();
while (ch < '0' || ch > '9') f |= ch == '-', ch = getchar();
while (ch >= '0' && ch <= '9') res = (res << 1) + (res << 3) + (ch ^ 48), ch = getchar();
return f ? -res : res;
}
int dfs(int pos, int p1, int p2, int p3, bool u1, bool u2, bool u3, bool x1, bool x2, bool x3) {
if (pos < 0) { return (! p1) && (! p2) && (! p3) && x1 && x2 && x3; }
if (dp[pos][p1][p2][p3][u1][u2][u3][x1][x2][x3] != -1) return dp[pos][p1][p2][p3][u1][u2][u3][x1][x2][x3];
dp[pos][p1][p2][p3][u1][u2][u3][x1][x2][x3] = 0;
for (int i = 0; i <= (u1 ? a[pos] : 1); ++ i)
for (int j = 0; j <= (u2 ? a[pos] : 1); ++ j)
if ((i ^ j) <= (u3 ? a[pos] : 1)) {
dp[pos][p1][p2][p3][u1][u2][u3][x1][x2][x3] += dfs(pos - 1, ((p1 << 1) + i) % a1, ((p2 << 1) + i) % a2, ((p3 << 1) + (i ^ j)) % a3, u1 && i == a[pos], u2 && j == a[pos], u3 && (i ^ j) == a[pos], x1 || i, x2 || j, x3 || (i ^ j)),
dp[pos][p1][p2][p3][u1][u2][u3][x1][x2][x3] %= mod;
}
return dp[pos][p1][p2][p3][u1][u2][u3][x1][x2][x3];
}
signed main() {
n = rd(), a1 = rd(), a2 = rd(), a3 = rd();
memset(dp, -1, sizeof (dp));
for (int i = 0; i <= 62; ++ i) a[i] = (n >> i) & 1; //
printf("%lld\n", dfs(62, 0, 0, 0, 1, 1, 1, 0, 0, 0)); //
return 0;
}
样例3就错了 QwQ
in
31415926535897932 3 8 4
out
759934997
mine
558666150