QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#708983#8077. Alice and BobemsgerTL 0ms3612kbC++202.4kb2024-11-04 10:27:522024-11-04 10:27:54

Judging History

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

  • [2024-11-04 10:27:54]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3612kb
  • [2024-11-04 10:27:52]
  • 提交

answer

#define NO_FREOPEN

#include <algorithm>
#include <array>
#include <iostream>
#include <vector>

using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;

void set_io(std::string name)
{
#ifndef NO_FREOPEN
  freopen((name + ".in").c_str(), "r", stdin);
  freopen((name + ".out").c_str(), "w", stdout);
#endif
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);
}

u64 binom(u64 n, u32 m)
{
  if (m < 0 || m > n) return 0;

  if (m == 1) return n;
  else if (m == 2) return n * (n - 1) / 2;
  else if (m == 3) return n * (n - 1) * (n - 2) / 6;
  else {
    u64 p = 1;
    u64 q = 1;
    for (u32 x = 0; x < m; x++) {
      p *= n - x;
      q *= x + 1;
    }
    return p / q;
  }
}

void solve()
{
  u32 n;
  std::cin >> n;

  u64 ans = binom(n, 3);

  std::vector<u64> a(n);
  for (auto &i : a) std::cin >> i;

  std::sort(a.begin(), a.end());

  std::vector<std::pair<u64, u32>> b;

  for (u32 i = 0; i < n; ) {
    u32 j = i;
    while (j < n && a[i] == a[j]) j++;
    u32 size = j - i;
    b.emplace_back(a[i], size);
    ans -= binom(size, 3);
    i = j;
  }

  u32 m = b.size();
  for (u32 i = 60; i--; ) {
    u32 mid = std::lower_bound(b.begin(), b.end(), 1ull << i, [](const std::pair<u64, u32> &b, u64 y)
                               {
                                 return b.first < y;
                               }) - b.begin();

    u64 mask = (1ull << i) - 1;

    for (auto &[v, _] : b) v &= mask;

    std::vector<std::pair<u64, u32>> c;
    u32 p = 0, q = mid;
    while (p < mid && q < m) {
      if (b[p].first < b[q].first) c.emplace_back(b[p++]);
      else if (b[p].first > b[q].first) c.emplace_back(b[q++]);
      else {
        u32 pr = p;
        u64 f1 = 0, f2 = 0;
        while (pr < mid && b[p].first == b[pr].first) {
          c.emplace_back(b[pr]);
          f1 += b[pr].second;
          f2 += binom(b[pr].second, 2);
          pr++;
        }
        if (i % 2 != 0) {
          f1 = 0;
          f2 = 0;
        }
        u32 qr = q;
        while (qr < m && b[q].first == b[qr].first) {
          c.emplace_back(b[qr]);
          ans -= f1 * binom(b[qr].second, 2);
          ans -= f2 * b[qr].second;
          qr++;
        }
        p = pr;
        q = qr;
      }
    }
    while (p < mid) c.emplace_back(b[p++]);
    while (q < m) c.emplace_back(b[q++]);

    b = std::move(c);
  }

  std::cout << ans << std::endl;
}

int main()
{
  set_io("game");

  int T;
  std::cin >> T;

  while (T--) solve();
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3612kb

input:

3
4
2 0 2 3
3
2 2 3
3
0 2 3

output:

3
0
1

result:

ok 3 lines

Test #2:

score: -100
Time Limit Exceeded

input:

1000000
3
63 98 95
3
61 38 97
3
7 73 98
3
1 10 91
3
94 31 99
3
96 54 97
3
14 44 99
3
81 51 97
3
96 95 92
3
35 90 98
3
7 39 96
3
71 8 96
3
36 35 99
3
82 52 96
3
89 53 99
3
76 85 95
3
80 34 91
3
9 13 99
3
12 17 94
3
40 4 95
3
57 5 93
3
47 69 93
3
23 0 94
3
62 44 97
3
7 4 99
3
21 97 99
3
41 3 99
3
36 9...

output:

1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
1
1
1
1
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
...

result: