QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#174661#7182. Very Sparse Tablehos_lyricAC ✓704ms29632kbC++145.7kb2023-09-10 11:54:592023-09-10 11:55:00

Judging History

This is the latest submission verdict.

  • [2023-09-10 11:55:00]
  • Judged
  • Verdict: AC
  • Time: 704ms
  • Memory: 29632kb
  • [2023-09-10 11:54:59]
  • Submitted

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")


constexpr int MAX_N = 1 << 16;
constexpr Int INF = 1001001001001001001LL;

Int dp[MAX_N + 1], prv[MAX_N + 1];

int N;
int counterAe;
vector<pair<int, pair<int, int>>> edges;
set<pair<int, int>> added;
void ae(int a, int b, int c) {
// cerr<<"[ae] "<<a<<" "<<b<<" "<<c<<endl;
  ++counterAe;
  assert(!added.emplace(a, b).second);
  assert(!added.emplace(b, c).second);
  if (added.emplace(a, c).second) {
    edges.emplace_back(a, make_pair(b, c));
  }
}
void build(int l, int r) {
  const int n = r - l;
  if (n <= 1) {
    return;
  }
  const int k = prv[n];
  const int quo = (n - k) / (k + 1);
  const int rem = (n - k) % (k + 1);
  vector<int> cuts(k + 2);
  cuts[0] = l;
  cuts[1] = l + quo;
  for (int j = 1; j <= k; ++j) {
    cuts[j + 1] = cuts[j] + 1 + (quo + ((j <= rem) ? 1 : 0));
  }
// cerr<<l<<" "<<r<<" "<<k<<": "<<cuts<<endl;
  assert(cuts[k + 1] == r);
  for (int j = 0; j <= k; ++j) {
    build(cuts[j] + (j ? 1 : 0), cuts[j + 1]);
  }
  // intra
  for (int j = 1; j <= k; ++j) {
    for (int i = cuts[j] - 2; i >= cuts[j - 1]; --i) {
      ae(i, i + 1, cuts[j]);
    }
    for (int i = cuts[j] + 2; i < cuts[j + 1]; ++i) {
      ae(cuts[j], i - 1, i);
    }
  }
  if (cuts[k] < r - 1) {
    ae(cuts[k], r - 1, r);
  }
  // inter
  for (int j0 = 1; j0 <= k; ++j0) {
    for (int j1 = j0 + 2; j1 <= k; ++j1) {
      ae(cuts[j0], cuts[j1 - 1], cuts[j1]);
    }
  }
}
int ansLen;
int ans[10];
void go(int a, int b) {
  assert(ans[ansLen - 1] == a);
  if (a < b) {
#ifdef LOCAL
// cerr<<"[go] "<<a<<" "<<b<<endl;
assert(!added.emplace(a,b).second);
#endif
    ans[ansLen++] = b;
  }
}
void dfs(int l, int r, int a, int b) {
  assert(l <= a); assert(a < b); assert(b <= r);
  const int n = r - l;
  if (n == 1) {
    go(a, b);
    return;
  }
  const int k = prv[n];
  const int quo = (n - k) / (k + 1);
  const int rem = (n - k) % (k + 1);
  auto cuts = [&](int j) -> int {
    assert(0 <= j); assert(j <= k + 1);
    return l + j * quo + max(j - 1, 0) + min(max(j - 1, 0), rem);
  };
  assert(cuts(0) == l);
  assert(cuts(k + 1) == r);
  int jA, jB;
  {
    int lo = 0, hi = k + 1;
    for (; lo + 1 < hi; ) {
      const int mid = (lo + hi) / 2;
      ((a <= cuts(mid)) ? hi : lo) = mid;
    }
    jA = hi;
  }
  {
    int lo = 0, hi = k + 1;
    for (; lo + 1 < hi; ) {
      const int mid = (lo + hi) / 2;
      ((cuts(mid) < b) ? lo : hi) = mid;
    }
    jB = lo;
  }
// cerr<<l<<" "<<r<<" "<<a<<" "<<b<<": "<<jA<<" "<<jB<<"; cuts = ";for(int j=0;j<=k;++j)cerr<<cuts(j)<<" ";cerr<<endl;
  const int aa = cuts(jA);
  const int bb = cuts(jB);
  if (aa <= bb) {
    go(a, aa);
    go(aa, bb);
    go(bb, b);
  } else {
    assert((jA - 1) + 1 == (jB + 1));
    dfs(cuts(jA - 1) + ((jA - 1) ? 1 : 0), cuts(jB + 1), a, b);
  }
}
void query(int a, int b) {
// cerr<<COLOR("33")<<"[query] "<<a<<" "<<b<<COLOR()<<endl;
  ansLen = 0;
  ans[ansLen++] = a;
  dfs(0, N, a, b);
  assert(ans[ansLen - 1] == b);
  assert(ansLen <= 4);
  for (int h = 0; h < ansLen; ++h) {
    if (h) printf(" ");
    printf("%d", ans[h]);
  }
  puts("");
  fflush(stdout);
}

int main() {
  dp[1] = 0;
  for (Int n = 2; n <= MAX_N; ++n) {
    dp[n] = INF;
    // k marked points
    // for (Int k = 2; k <= n; ++k) {
    for (Int k = 1; k <= n && k < 300; ++k) {
      const Int q = (n - k) / (k + 1);
      const Int r = (n - k) % (k + 1);
      Int cost = 0;
      // inter
      cost += k * (k - 1) / 2;
      // intra
      cost += min(r, k - 1) * 2 * max((q + 1) - 1, 0LL);
      cost += ((k - 1) - min(r, k - 1)) * 2 * max(q - 1, 0LL);
      cost += max(q - 1, 0LL);
      cost += max(((r >= k) ? (q + 1) : q) - 0, 0LL);
      // rec
      cost += r * dp[q + 1];
      cost += (k + 1 - r) * dp[q];
      if (chmin(dp[n], cost)) {
        prv[n] = k;
      }
    }
if(n<=16||!(n&(n-1))||dp[n]>6*n)cerr<<n<<": "<<dp[n]<<" "<<dp[n]/(double)n<<" "<<prv[n]<<endl;
    assert(dp[n] <= 6 * n);
  }
cerr<<"max prv = "<<*max_element(prv,prv+(MAX_N+1))<<endl;
  
  scanf("%d", &N);
  for (int i = 0; i < N; ++i) {
    added.emplace(i, i + 1);
  }
  build(0, N);
  printf("%d\n", (int)edges.size());
  for (const auto &edge : edges) {
    printf("%d %d %d\n", edge.first, edge.second.first, edge.second.second);
  }
  fflush(stdout);
  assert(counterAe == dp[N]);
  
#ifdef LOCAL
for(int a=0;a<=N;++a)for(int b=a+1;b<=N;++b)query(a,b);
#endif
  int Q;
  scanf("%d", &Q);
  for (; Q--; ) {
    int a, b;
    scanf("%d%d", &a, &b);
    query(a, b);
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 77ms
memory: 5096kb

input:

9
45
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
2 3
2 4
2 5
2 6
2 7
2 8
2 9
3 4
3 5
3 6
3 7
3 8
3 9
4 5
4 6
4 7
4 8
4 9
5 6
5 7
5 8
5 9
6 7
6 8
6 9
7 8
7 9
8 9

output:

7
1 2 3
3 4 5
5 6 7
7 8 9
1 3 5
1 5 7
3 5 7
0 1
0 1 2
0 1 3
0 1 3 4
0 1 3 5
0 1 5 6
0 1 5 7
0 1 7 8
0 1 7 9
1 2
1 3
1 3 4
1 3 5
1 5 6
1 5 7
1 7 8
1 7 9
2 3
2 3 4
2 3 5
2 3 5 6
2 3 5 7
2 3 7 8
2 3 7 9
3 4
3 5
3 5 6
3 5 7
3 7 8
3 7 9
4 5
4 5 6
4 5 7
4 5 7 8
4 5 7 9
5 6
5 7
5 7 8
5 7 9
6 7
6 7 8
6 7 9
...

result:

ok edges: 7

Test #2:

score: 0
Accepted
time: 78ms
memory: 4960kb

input:

30
465
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
0 10
0 11
0 12
0 13
0 14
0 15
0 16
0 17
0 18
0 19
0 20
0 21
0 22
0 23
0 24
0 25
0 26
0 27
0 28
0 29
0 30
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20
1 21
1 22
1 23
1 24
1 25
1 26
1 27
1 28
1 29
1 30
2 3
2 4
2 5
2 6...

output:

49
1 2 3
3 4 5
6 7 8
8 9 10
10 11 12
6 8 10
14 15 16
16 17 18
20 21 22
22 23 24
26 27 28
28 29 30
2 3 5
1 2 5
0 1 5
5 6 7
5 7 8
5 8 9
5 9 10
5 10 11
9 10 12
8 9 12
7 8 12
6 7 12
5 6 12
12 13 14
12 14 15
12 15 16
12 16 17
15 16 18
14 15 18
13 14 18
12 13 18
18 19 20
18 20 21
18 21 22
18 22 23
21 22 2...

result:

ok edges: 49

Test #3:

score: 0
Accepted
time: 478ms
memory: 5192kb

input:

736
200000
170 268
126 166
565 723
664 735
61 524
226 234
146 314
217 272
294 713
115 381
563 706
74 567
552 614
120 211
472 620
213 432
488 623
447 564
96 129
331 354
79 677
50 547
174 568
56 129
189 227
55 701
244 253
264 715
154 220
380 657
46 390
53 161
325 537
666 696
64 465
391 659
284 448
207...

output:

2661
0 1 2
2 3 4
6 7 8
8 9 10
12 13 14
14 15 16
18 19 20
20 21 22
24 25 26
26 27 28
1 2 4
0 1 4
4 5 6
4 6 7
4 7 8
4 8 9
7 8 10
6 7 10
5 6 10
4 5 10
10 11 12
10 12 13
10 13 14
10 14 15
13 14 16
12 13 16
11 12 16
10 11 16
16 17 18
16 18 19
16 19 20
16 20 21
19 20 22
18 19 22
17 18 22
16 17 22
22 23 24...

result:

ok edges: 2661

Test #4:

score: 0
Accepted
time: 704ms
memory: 29572kb

input:

65536
200000
51949 58727
7943 43298
6290 7369
41493 53070
24229 36675
28087 49947
11703 48217
19923 24739
2144 59777
53830 56793
13509 37211
2300 38595
27415 42879
24616 48531
58341 63327
20628 38407
48616 60290
7450 61685
37010 47595
22164 42732
19181 29850
35383 43587
39257 44397
19340 45183
34523...

output:

359330
1 2 3
3 4 5
7 8 9
9 10 11
13 14 15
15 16 17
19 20 21
21 22 23
2 3 5
1 2 5
0 1 5
5 6 7
5 7 8
5 8 9
5 9 10
8 9 11
7 8 11
6 7 11
5 6 11
11 12 13
11 13 14
11 14 15
11 15 16
14 15 17
13 14 17
12 13 17
11 12 17
17 18 19
17 19 20
17 20 21
17 21 22
17 22 23
5 11 17
25 26 27
27 28 29
31 32 33
33 34 35...

result:

ok edges: 359330

Test #5:

score: 0
Accepted
time: 76ms
memory: 5120kb

input:

0
0

output:

0

result:

ok edges: 0

Test #6:

score: 0
Accepted
time: 75ms
memory: 4900kb

input:

1
1
0 1

output:

0
0 1

result:

ok edges: 0

Test #7:

score: 0
Accepted
time: 79ms
memory: 4844kb

input:

2
3
0 1
0 2
1 2

output:

1
0 1 2
0 1
0 2
1 2

result:

ok edges: 1

Test #8:

score: 0
Accepted
time: 75ms
memory: 4896kb

input:

3
6
0 1
0 2
0 3
1 2
1 3
2 3

output:

1
1 2 3
0 1
0 1 2
0 1 3
1 2
1 3
2 3

result:

ok edges: 1

Test #9:

score: 0
Accepted
time: 621ms
memory: 28836kb

input:

65535
200000
35006 46944
17075 57351
24605 50445
5938 60705
15221 40233
28599 38915
1132 35574
8555 31494
13644 35806
44940 55401
9503 59206
21011 26540
41156 62487
57510 64305
9254 25610
17301 47249
34083 49167
48018 64394
38855 62175
15464 22525
23728 60275
54028 63810
22711 53902
5984 48625
5838 ...

output:

359322
1 2 3
3 4 5
7 8 9
9 10 11
13 14 15
15 16 17
19 20 21
21 22 23
2 3 5
1 2 5
0 1 5
5 6 7
5 7 8
5 8 9
5 9 10
8 9 11
7 8 11
6 7 11
5 6 11
11 12 13
11 13 14
11 14 15
11 15 16
14 15 17
13 14 17
12 13 17
11 12 17
17 18 19
17 19 20
17 20 21
17 21 22
17 22 23
5 11 17
25 26 27
27 28 29
31 32 33
33 34 35...

result:

ok edges: 359322

Test #10:

score: 0
Accepted
time: 698ms
memory: 29632kb

input:

64800
200000
55124 62263
24992 39760
32262 37059
25987 42889
10413 64701
7223 43221
45810 63205
11437 29357
10814 52096
1154 36319
10730 54157
18473 26729
9152 23374
5426 12744
3502 37577
5559 37160
30503 62433
12426 47332
14933 62086
8781 21527
27180 53773
29658 46742
20592 61553
8337 27197
8024 38...

output:

355067
1 2 3
3 4 5
7 8 9
9 10 11
13 14 15
15 16 17
19 20 21
21 22 23
2 3 5
1 2 5
0 1 5
5 6 7
5 7 8
5 8 9
5 9 10
8 9 11
7 8 11
6 7 11
5 6 11
11 12 13
11 13 14
11 14 15
11 15 16
14 15 17
13 14 17
12 13 17
11 12 17
17 18 19
17 19 20
17 20 21
17 21 22
17 22 23
5 11 17
25 26 27
27 28 29
31 32 33
33 34 35...

result:

ok edges: 355067

Extra Test:

score: 0
Extra Test Passed