[ SDOI 2016 ] 儲能表
阿新 • • 發佈:2021-06-11
題目
思路
程式碼
#include <iostream> #include <cstring> #include <algorithm> #define int long long using namespace std; const int N = 65; int f[N][2][2][2], g[N][2][2][2], T; signed main() { cin >> T; for (int n, m, k, p; T-- && cin >> n >> m >> k >> p; ) { memset(f, 0, sizeof f), memset(g, 0, sizeof g), g[61][1][1][1] = 1; for (int i = 60; i >= 0; i--) { int q = (n >> i) & 1, w = (m >> i) & 1, e = (k >> i) & 1; for (int a = 0; a < 2; a++) for (int b = 0; b < 2; b++) for (int c = 0; c < 2; c++) if (f[i + 1][a][b][c] || g[i + 1][a][b][c]) for (int x = 0; x < 2; x++) for (int y = 0; y < 2; y++) { int z = x ^ y; if ((a && x > q) || (b && y > w) || (c && z < e)) continue; int s = (a && x == q), u = (b && y == w), v = (c && z == e); g[i][s][u][v] = (g[i][s][u][v] + g[i + 1][a][b][c]) % p; f[i][s][u][v] = (f[i][s][u][v] + f[i + 1][a][b][c] + (z - e + p) % p * ((1ll << i) % p) % p * g[i + 1][a][b][c] % p) % p; } } cout << f[0][0][0][0] << endl; } return 0; }