QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#747872#5219. 随机树生成器hos_lyric40 964ms35648kbC++149.4kb2024-11-14 18:32:462024-11-14 18:32:47

Judging History

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

  • [2024-11-14 18:32:47]
  • 评测
  • 测评结果:40
  • 用时:964ms
  • 内存:35648kb
  • [2024-11-14 18:32:46]
  • 提交

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 <random>
#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")


// (without edge property)
// sub[u]: inside subtree at u, rooted at u
// bus[u]: outside subtree at u, rooted at par[u]
// tot[u]: rooted at u
// T: monoid representing information of a subtree.
//   T::init()  should assign the identity.
//   T::pull(const T &l, const T &r)  should assign the product.
//   T::up(int u)  should attach vertex u to the product of the subtrees.
template <class T> struct ForestDP {
  int n;
  vector<vector<int>> graph;
  vector<int> par;
  vector<T> sub, bus, tot;

  ForestDP() : n(0) {}
  explicit ForestDP(int n_) : n(n_), graph(n_) {}
  void ae(int u, int v) {
    assert(0 <= u); assert(u < n);
    assert(0 <= v); assert(v < n);
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  void run() {
    par.assign(n, -2);
    sub.resize(n);
    bus.resize(n);
    tot.resize(n);
    for (int u = 0; u < n; ++u) if (par[u] == -2) {
      dfs0(u, -1);
      dfs1(u, -1);
    }
  }
  void dfs0(int u, int p) {
    par[u] = p;
    const int deg = graph[u].size();
    int w = -1;
    for (int j = deg; --j >= 0; ) {
      const int v = graph[u][j];
      if (p != v) {
        dfs0(v, u);
        if (~w) {
          bus[v].pull(sub[v], bus[w]);
        } else {
          bus[v] = sub[v];
        }
        w = v;
      }
    }
    if (~w) {
      sub[u] = bus[w];
    } else {
      sub[u].init();
    }
    sub[u].up(u);
  }
  void dfs1(int u, int p) {
    const int deg = graph[u].size();
    int v = -1;
    for (int j = 0; j < deg; ++j) {
      const int w = graph[u][j];
      if (p != w) {
        if (~v) {
          bus[v].pull(tot[v], bus[w]);
          bus[v].up(u);
          tot[w].pull(tot[v], sub[v]);
          dfs1(v, u);
        } else {
          if (~p) {
            tot[w] = bus[u];
          } else {
            tot[w].init();
          }
        }
        v = w;
      }
    }
    if (~v) {
      bus[v] = tot[v];
      bus[v].up(u);
      tot[u].pull(tot[v], sub[v]);
      dfs1(v, u);
    } else {
      if (~p) {
        tot[u] = bus[u];
      } else {
        tot[u].init();
      }
    }
    tot[u].up(u);
  }
};

vector<int> uf;
int root(int u) {
  return (uf[u] < 0) ? u : (uf[u] = root(uf[u]));
}
bool connect(int u, int v) {
  u = root(u);
  v = root(v);
  if (u == v) return false;
  if (uf[u] > uf[v]) swap(u, v);
  uf[u] += uf[v];
  uf[v] = u;
  return true;
}


constexpr int N = 1000;
const vector<vector<int>> TSS{
  {1, 2, 3, 4},
  {1, 2},
  {1, 2, 3},
  {1, 3, 4},
  {1, 2, 3, 4},
  {1, 2, 3, 4},
};

vector<vector<int>> graph;
void init() {
  graph.assign(N, {});
}
void ae(int u, int v) {
  graph[u].push_back(v);
  graph[v].push_back(u);
}

// diameter
// \sum[u] \max[v] dist(u, v)
namespace diam {
struct Data {
  int mx;
  Data() : mx(0) {}
  void init() {
    mx = 0;
  }
  void pull(const Data &l, const Data &r) {
    mx = max(l.mx, r.mx);
  }
  void up(int) {
    mx += 1;
  }
};
pair<int, int> run() {
  ForestDP<Data> f(N);
  for (int u = 0; u < N; ++u) for (const int v : graph[u]) if (u < v) f.ae(u, v);
  f.run();
  int mx = 0, sum = 0;
  for (int u = 0; u < N; ++u) {
    const int d = f.tot[u].mx - 1;
    chmax(mx, d);
    sum += d;
  }
  return make_pair(mx, sum);
}
}  // diam

// take centroid, \sum[u] log(sz[u])
namespace sum_log_sz {
vector<int> sz;
void dfs(int u, int p) {
  for (const int v : graph[u]) if (p != v) {
    dfs(v, u);
    sz[u] += sz[v];
  }
}
double run() {
  sz.assign(N, 1);
  dfs(0, -1);
  for (int u = 0; ; ) {
    int vm = -1;
    for (const int v : graph[u]) {
      if (!~vm || sz[vm] < sz[v]) vm = v;
    }
    if (!~vm || 2 * sz[vm] <= sz[u]) {
      break;
    } else {
      sz[u] -= sz[vm];
      sz[vm] += sz[u];
      u = vm;
    }
  }
  double sum = 0.0;
  for (int u = 0; u < N; ++u) sum += log((double)sz[u]);
  return sum;
}
}  // sum_log_sz

constexpr int Z = 3;

double thresh(double a, double p, double b, double q) {
  return (q * a + p * b) / (q + p);
}
bool can[4];
int solve(const double fs[Z]) {
  if (can[0] && fs[2] < thresh(786.534, 15.5531, 1111.27, 25.7229)) return 0;
  if (can[3] && fs[2] > thresh(1200.07, 38.5273, 1435.13, 53.7659)) return 3;
  if (can[1] && fs[1] < thresh(32749, 2780.57, 50541.4, 7260.11)) return 1;
  if (can[2]) return 2;
  return 1;
}

void exper() {
  constexpr int K = 100'000;
  fill(can, can + 4, true);
  for (int t = 0; t < 4; ++t) {
    double mn[Z], mx[Z], avg[Z] = {}, dev[Z] = {};
    fill(mn, mn + Z, +1e+100);
    fill(mx, mx + Z, -1e+100);
    int freq[4] = {};
    for (int k = 0; k < K; ++k) {
      init();
      mt19937_64 rng(k * 4 + t);
      if (t == 0 || t == 1) {
        vector<int> perm(N);
        for (int u = 0; u < N; ++u) swap(perm[rng() % (u + 1)], perm[u] = u);
        perm.insert(perm.begin(), -1);
        for (int i = 2; i <= N; ++i) {
          const int l = (t == 0) ? 1 : (i / 2);
          const int r = i - 1;
          ae(perm[i], perm[l + rng() % (r - l + 1)]);
        }
      } else if (t == 2) {
        uf.assign(N, -1);
        for (int numComps = N; numComps > 1; ) {
          const int u = rng() % N;
          const int v = rng() % N;
          if (connect(u, v)) {
            ae(u, v);
            --numComps;
          }
        }
      } else if (t == 3) {
        vector<int> seq(N - 2);
        for (int i = 0; i < N - 2; ++i) seq[i] = rng() % N;
        vector<int> deg(N, 1);
        for (int i = 0; i < N - 2; ++i) ++deg[seq[i]];
        priority_queue<int, vector<int>, greater<int>> que;
        for (int u = 0; u < N; ++u) if (deg[u] == 1) que.push(u);
        for (int i = 0; i < N - 2; ++i) {
          const int u = que.top(); que.pop();
          const int v = seq[i];
          ae(u, v);
          if (--deg[v] == 1) que.push(v);
        }
        {
          const int u = que.top(); que.pop();
          const int v = que.top(); que.pop();
          ae(u, v);
        }
      } else {
        assert(false);
      }
      
      double fs[Z];
      const auto res01 = diam::run();
      fs[0] = res01.first;
      fs[1] = res01.second;
      fs[2] = sum_log_sz::run();
      for (int z = 0; z < Z; ++z) {
        chmin(mn[z], fs[z]);
        chmax(mx[z], fs[z]);
        avg[z] += fs[z];
        dev[z] += fs[z] * fs[z];
      }
      ++freq[solve(fs)];
    }
    cerr << "t = " << t << ": freq = "; pv(freq, freq + 4);
    for (int z = 0; z < Z; ++z) {
      avg[z] /= K;
      dev[z] /= K;
      dev[z] -= avg[z] * avg[z];
      dev[z] = sqrt(dev[z]);
      cerr << "  z = " << z << ": " << mn[z] << " " << mx[z] << " " << avg[z] << " " << dev[z] << endl;
    }
  }
}
/*
K = 10^5
t = 0: freq = 100000 0 0 0
  z = 0: 19 37 25.1975 2.05855
  z = 1: 14614 28463 18921.2 1389
  z = 2: 713.99 855.405 786.534 15.5531
t = 1: freq = 0 95669 4331 0
  z = 0: 29 57 40.4774 3.28401
  z = 1: 23208 46925 32749 2780.57
  z = 2: 1005.01 1222.99 1111.27 25.7229
t = 2: freq = 0 1764 97417 819
  z = 0: 39 125 67.1403 9.69939
  z = 1: 28704 94493 50541.4 7260.11
  z = 2: 1053.2 1392.09 1200.07 38.5273
t = 3: freq = 0 0 280 99720
  z = 0: 52 197 99.7902 15.828
  z = 1: 38560 149429 75556.2 12017.2
  z = 2: 1223.04 1700 1435.13 53.7659
*/

int O, M;
vector<vector<int>> A, B;

int main() {
  // exper(); return 0;
  
  for (; ~scanf("%d", &O); ) {
    scanf("%d", &M);
    A.resize(M);
    B.resize(M);
    for (int m = 0; m < M; ++m) {
      A[m].resize(N - 1);
      B[m].resize(N - 1);
      for (int i = 0; i < N - 1; ++i) {
        scanf("%d%d", &A[m][i], &B[m][i]);
        --A[m][i];
        --B[m][i];
      }
    }
    
    fill(can, can + 4, true);
    if (O == 1) can[2] = can[3] = false;
    if (O == 2) can[3] = false;
    if (O == 3) can[2] = false;
    
    vector<int> ans(M);
    for (int m = 0; m < M; ++m) {
      init();
      for (int i = 0; i < N - 1; ++i) ae(A[m][i], B[m][i]);
      double fs[Z];
      const auto res01 = diam::run();
      fs[0] = res01.first;
      fs[1] = res01.second;
      fs[2] = sum_log_sz::run();
      ans[m] = solve(fs);
    }
    
    for (int m = 0; m < M; ++m) {
      printf("%d\n", ans[m] + 1);
    }
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Pretests


Final Tests

Test #1:

score: 20
Accepted
time: 458ms
memory: 20152kb

input:

1
2000
108 829
559 321
202 439
722 254
969 38
682 607
7 289
4 515
960 182
738 434
884 235
948 715
201 396
41 593
343 602
784 70
69 573
764 136
320 908
475 571
16 273
792 656
636 423
800 685
43 560
117 436
368 645
713 116
750 549
60 950
435 460
175 572
874 628
878 408
497 865
994 833
761 21
257 541
8...

output:

1
2
1
2
2
1
1
1
1
2
1
2
2
1
1
2
2
1
2
2
2
1
2
2
2
1
2
2
1
2
2
1
2
1
1
2
1
1
2
2
2
1
1
2
2
2
2
1
1
2
1
1
2
1
2
2
2
2
1
1
1
2
2
1
2
1
2
1
1
1
1
2
2
1
2
2
2
2
1
1
1
1
2
1
2
1
1
1
2
1
2
1
2
1
2
1
2
1
2
2
1
1
2
1
1
1
1
2
2
2
2
1
2
2
2
1
2
1
2
2
1
1
1
2
2
2
1
2
2
1
1
1
2
2
1
1
2
1
2
2
2
1
2
1
2
1
1
1
1
2
...

result:

ok wrong 0 "ok"
10

Test #2:

score: 8
Acceptable Answer
time: 711ms
memory: 28068kb

input:

2
3000
385 547
858 608
546 731
753 57
849 806
659 442
208 260
844 77
344 530
171 29
278 228
863 72
379 395
554 829
488 650
554 281
139 67
190 479
894 587
819 872
936 543
862 985
99 202
778 317
317 500
41 420
713 562
616 863
691 743
673 49
702 705
358 910
254 665
617 579
142 926
433 634
446 299
647 8...

output:

2
3
1
1
1
2
3
1
2
1
2
3
2
2
3
1
3
1
2
2
1
3
3
2
1
3
3
1
1
1
2
2
1
3
1
2
2
3
2
3
3
1
2
1
2
2
1
1
2
3
2
1
3
2
2
2
1
2
3
1
2
2
1
3
3
3
1
3
1
1
2
2
2
3
1
2
3
3
3
3
3
3
2
3
3
3
2
3
2
3
2
2
3
2
3
1
3
2
1
3
3
3
1
3
2
2
2
3
3
2
3
2
1
3
3
2
1
2
1
2
3
2
3
1
1
1
2
3
3
2
1
3
3
3
1
3
2
1
1
1
2
1
1
3
2
1
2
2
2
2
...

result:

points 0.40 wrong 60 "ok"
4

Test #3:

score: 0
Wrong Answer
time: 716ms
memory: 27936kb

input:

3
3000
919 530
286 438
406 142
171 904
81 225
259 921
109 783
590 200
601 353
448 647
914 29
122 830
926 632
604 1
408 599
624 276
156 744
269 895
965 962
17 789
210 90
283 203
25 294
167 916
945 707
673 840
769 947
272 879
836 341
175 506
753 813
889 328
908 477
156 638
166 835
127 235
369 528
896 ...

output:

4
4
2
4
1
4
4
2
4
4
4
2
4
2
2
2
1
2
2
2
4
4
4
2
4
4
2
2
2
1
4
2
2
4
1
4
1
2
2
4
1
1
1
2
1
2
1
1
4
4
1
2
1
1
1
4
2
4
2
1
4
1
2
1
2
1
1
2
4
2
2
1
1
1
1
1
4
4
2
2
2
2
4
4
2
1
1
1
2
1
2
2
1
1
1
1
1
1
2
4
2
2
4
2
4
1
4
4
1
2
2
1
2
1
1
2
4
2
4
2
1
1
1
2
1
4
1
1
4
4
2
2
1
2
2
4
2
4
4
1
4
2
2
4
2
2
4
4
1
1
...

result:

points 0.0 wrong 1005 "ok"
0

Test #4:

score: 10
Acceptable Answer
time: 964ms
memory: 35604kb

input:

4
4000
491 790
856 346
110 718
170 643
428 723
333 382
373 986
352 227
190 993
896 507
660 720
691 733
867 854
136 794
208 769
739 362
431 624
608 1000
576 185
268 330
944 962
10 631
791 594
660 581
716 661
847 413
613 859
203 104
155 426
471 785
864 132
106 534
727 979
476 353
561 186
38 291
596 82...

output:

2
1
2
4
1
2
2
1
4
4
2
3
4
2
4
2
1
3
4
3
4
3
4
3
4
3
4
4
4
1
2
4
1
3
2
3
1
3
2
1
4
2
2
1
1
2
2
3
1
1
4
1
1
1
4
3
1
1
2
4
3
1
2
4
1
1
3
3
3
4
3
2
2
1
2
3
4
3
3
1
3
3
4
4
3
2
2
2
3
3
4
3
4
1
1
2
3
2
3
1
3
1
1
4
1
1
2
1
4
3
2
4
2
1
2
3
1
2
2
4
4
1
4
1
3
3
2
3
4
4
4
3
4
4
1
2
3
3
1
2
3
3
2
1
1
2
2
1
4
1
...

result:

points 0.50 wrong 65 "ok"
5

Test #5:

score: 2
Acceptable Answer
time: 962ms
memory: 35648kb

input:

5
4000
524 666
160 834
416 567
371 589
472 27
790 459
856 424
688 446
169 197
837 492
137 22
5 721
232 666
878 621
140 199
976 987
610 272
565 196
409 552
853 327
161 175
957 253
732 108
344 6
443 458
846 21
710 93
579 650
833 211
358 450
714 920
778 197
181 355
1000 87
395 180
800 763
69 553
74 887...

output:

3
4
3
4
2
3
1
4
3
3
2
3
4
4
3
3
2
4
3
2
2
2
1
2
2
2
3
4
4
3
4
4
3
2
3
3
3
4
3
4
4
2
1
3
4
4
2
2
3
1
4
4
3
4
1
2
4
2
4
3
1
1
4
4
1
2
1
2
1
1
3
3
4
4
1
4
2
4
4
1
1
1
3
2
3
2
1
3
1
2
1
2
1
4
1
2
3
2
1
4
2
1
1
4
1
1
1
3
4
3
2
2
4
4
2
4
2
3
4
3
4
2
1
1
1
4
4
2
1
2
2
1
1
1
2
4
1
1
2
3
2
2
4
3
2
3
4
1
3
3
...

result:

points 0.10 wrong 70 "ok"
1