QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#308296#6655. 巧克力ckisekiTL 0ms0kbC++203.6kb2024-01-19 20:48:072024-01-19 20:48:07

Judging History

你现在查看的是最新测评结果

  • [2024-01-19 20:48:07]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-01-19 20:48:07]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

namespace {

constexpr int mod = 1'000'000'007;

constexpr int add(int a, int b) {
  return a + b >= mod ? a + b - mod : a + b;
}
constexpr int sub(int a, int b) {
  return a - b < 0 ? a - b + mod : a - b;
}
constexpr int mul(int64_t a, int64_t b) {
  return static_cast<int>(a * b % mod);
}

int visc;
int vis1[64][2][2][2];
int dp1[64][2][2][2];

bool xd[64];
bool d1[64], d2[64];

int go1(int p, bool any1, bool any2, bool carry) {
  if (p == -1) {
    return not carry;
  }
  if (vis1[p][any1][any2][carry] == visc) {
    return dp1[p][any1][any2][carry];
  }
  vis1[p][any1][any2][carry] = visc;

  int ans = 0;
  for (int i : {0, 1}) {
    for (int j : {0, 1}) {
      if (not any2 and (i ^ j ^ xd[p]) > d2[p])
        continue;
      for (int b : {0, 1}) {
        if (not any1 and (i + j + b) % 2 > d1[p])
          continue;
        if (i + j + b > 1) {
          if (not carry)
            continue;
          ans = add(ans, go1(p - 1, any1 or (i + j + b) % 2 < d1[p], any2 or (i ^ j ^ xd[p]) < d2[p], b));
        } else {
          if (carry)
            continue;
          ans = add(ans, go1(p - 1, any1 or (i + j + b) % 2 < d1[p], any2 or (i ^ j ^ xd[p]) < d2[p], b));
        }
      }
    }
  }

  cout << "dp1[" << p << "][" << any1 << "][" << any2 << "][" << carry << "] = " << ans << '\n';
  return dp1[p][any1][any2][carry] = ans;
}

int solve1(uint64_t x, uint64_t fi, uint64_t se) {
  memset(d1, 0, sizeof(d1));
  memset(d2, 0, sizeof(d2));

  int xdc = 63;
  for (uint64_t o = x; o; o /= 2)
    xd[xdc--] = o & 1;

  int d1c = 63;
  for (uint64_t o = fi; o; o /= 2)
    d1[d1c--] = o & 1;

  int d2c = 63;
  for (uint64_t o = se; o; o /= 2)
    d2[d2c--] = o & 1;

  visc += 1;
  return go1(63, 0, 0, 0);
}

int vis2[64][2][2][2];
int dp2[64][2][2][2];

int go2(int p, bool any1, bool any2, bool carry) {
  if (p == -1) {
    return not carry;
  }
  if (vis2[p][any1][any2][carry] == visc) {
    return dp2[p][any1][any2][carry];
  }
  vis2[p][any1][any2][carry] = visc;
  int ans = 0;
  for (int i : {0, 1}) {
    for (int j : {0, 1}) {
      if (not any2 and (i ^ j ^ xd[p]) > (i + j + carry) % 2)
        continue;
      for (int b : {0, 1}) {
        if (not any1 and (i + j + b) % 2 > d1[p])
          continue;
        if (i + j + b > 1) {
          if (not carry)
            continue;
          ans = add(ans, go1(p - 1, any1 or (i + j + b) % 2 < d1[p], any2 or (i ^ j ^ xd[p]) < (i + j + carry) % 2, b));
        } else {
          if (carry)
            continue;
          ans = add(ans, go1(p - 1, any1 or (i + j + b) % 2 < d1[p], any2 or (i ^ j ^ xd[p]) < (i + j + carry) % 2, b));
        }
      }
    }
  }
  return dp2[p][any1][any2][carry] = ans;
}

int solve2(uint64_t x, uint64_t n) {
  memset(d1, 0, sizeof(d1));

  int xdc = 63;
  for (uint64_t o = x; o; o /= 2)
    xd[xdc--] = o & 1;

  int d1c = 63;
  for (uint64_t o = n; o; o /= 2)
    d1[d1c--] = o & 1;

  visc += 1;
  int ret = go2(63, 0, 0, 0);
  cout << "solve2(" << x << ", " << n << ") = " << ret << '\n';
  return ret;
}

int solve(uint64_t n, uint64_t m) {
  uint64_t x = m;
  for (uint64_t v = n / 4 * 4; v <= n; ++v)
    x ^= v;

  cout << "x = " << x << endl;

  int ans = 0;
  if (n > 0) {
    ans = add(ans, solve1(x, n - 1, n));
    ans = sub(ans, solve2(x, n - 1));
  }
  if (m > 0) {
    ans = add(ans, solve1(x, m - 1, m));
    ans = sub(ans, solve1(x, m - 1, m - 1));
  }
  return ans;
}

} // namespace

int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  int t;
  cin >> t;
  while (t--) {
    uint64_t n, m;
    cin >> n >> m;
    cout << solve(n, m) << '\n';
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

input:

50000
0 0
0 1
0 2
0 3
0 4
0 5
1 0
1 1
1 2
1 3
1 4
1 5
2 0
2 1
2 2
2 3
2 4
2 5
3 0
3 1
3 2
3 3
3 4
3 5
4 0
4 1
4 2
4 3
4 4
4 5
5 0
5 1
5 2
5 3
5 4
5 5
0 2000000013
3 2000000013
960420868510113883 392659194919473988
668803384430801620 162045456939453012
617795168362576047 722239203838631701
6050650100...

output:

x = 0
0
x = 1
dp1[0][0][0][0] = 1
dp1[1][0][0][0] = 1
dp1[2][0][0][0] = 1
dp1[3][0][0][0] = 1
dp1[4][0][0][0] = 1
dp1[5][0][0][0] = 1
dp1[6][0][0][0] = 1
dp1[7][0][0][0] = 1
dp1[8][0][0][0] = 1
dp1[9][0][0][0] = 1
dp1[10][0][0][0] = 1
dp1[11][0][0][0] = 1
dp1[12][0][0][0] = 1
dp1[13][0][0][0] = 1
dp...

result: