[ SDOI 2016 ] 储能表

题目

Luogu
LOJ
Acwing

思路

[ SDOI 2016 ] 储能表[ SDOI 2016 ] 储能表

代码

#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;
}
上一篇:[ SDOI 2017 ] 新生舞会


下一篇:SDOI 选做