QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#118829#5445. Vulpeculahos_lyricTL 146ms5420kbC++147.1kb2023-07-04 13:20:452023-07-04 13:20:45

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-04 13:20:45]
  • 评测
  • 测评结果:TL
  • 用时:146ms
  • 内存:5420kb
  • [2023-07-04 13:20:45]
  • 提交

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; }


// (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);
  }
};

////////////////////////////////////////////////////////////////////////////////

using U = unsigned long long;
int bsr(U x) {
  return 63 - __builtin_clzll(x);
}

constexpr int E = 64;
// #ifdef LOCAL
// constexpr int E = 7;
// #endif

int N;
vector<int> P;
vector<int> M;
vector<vector<U>> X;

struct Data {
  // (d, x): at depth d, add x to ann
  int len;
  pair<int, U> ps[E];
  void add(int d, U x) {
    for (int i = 0; i < len; ++i) {
      chmin(x, x ^ ps[i].second);
    }
    if (x) {
assert(len<E);
      ps[len++] = make_pair(d, x);
    }
  }

  void init() {
    len = 0;
  }
  void pull(const Data &a, const Data &b) {
    len = 0;
    for (int i = 0, j = 0; i < a.len || j < b.len; ) {
      if (i < a.len && ((j == b.len || a.ps[i].first < b.ps[j].first))) {
        add(a.ps[i].first, a.ps[i].second);
        ++i;
      } else {
        add(b.ps[j].first, b.ps[j].second);
        ++j;
      }
    }
  }
  void up(int u);

  U solve() const {
// cerr<<"solve ";pv(ps,ps+len);
    U ans = 0;
    int d = 0;
    U now = (E == 64) ? ~0ULL : ((1ULL << E) - 1);
    
    U xs[E];
    int bsrs[E];
    U used;
    int DIM;
    U BASIS[E];
    U MX;
    for (int i = 0; i < len; ++i) {
// cerr<<"["<<d<<", "<<ps[i].first<<"): "<<now<<endl;
      ans += (ps[i].first - d) * now;
      d = ps[i].first;
      
      for (int j = 0; j <= i; ++j) {
        xs[j] = ps[j].second;
      }
      for (int j = 0; j <= i; ++j) {
        for (int k = j + 1; k <= i; ++k) {
          chmin(xs[j], xs[j] ^ xs[k]);
        }
      }
      used = 0ULL;
      for (int j = 0; j <= i; ++j) {
        bsrs[j] = bsr(xs[j]);
        used |= 1ULL << bsrs[j];
      }
      DIM = 0;
      MX = 0;
      for (int e = 0; e < E; ++e) if (!(used & 1ULL << e)) {
        U z = 1ULL << e;
        for (int j = 0; j <= i; ++j) if (xs[j] & 1ULL << e) {
          z |= 1ULL << bsrs[j];
        }
        for (int I = 0; I < DIM; ++I) {
          chmin(z, z ^ BASIS[I]);
        }
        assert(z);
        BASIS[DIM++] = z;
        chmax(MX, MX ^ z);
      }
      now = MX;
    }
// cerr<<"["<<d<<", "<<N<<"): "<<now<<endl;
    ans += (N - d) * now;
    return ans;
  }
};

vector<Data> anns;
void Data::up(int u) {
  Data a = *this;
  *this = anns[u];
  for (int i = 0; i < a.len; ++i) {
    add(1 + a.ps[i].first, a.ps[i].second);
  }
}

int main() {
  for (; ~scanf("%d", &N); ) {
    P.assign(N, -1);
    for (int u = 1; u < N; ++u) {
      scanf("%d", &P[u]);
      --P[u];
    }
    M.resize(N);
    X.resize(N);
    for (int u = 0; u < N; ++u) {
      scanf("%d", &M[u]);
      X[u].resize(M[u]);
      for (U &x : X[u]) {
        scanf("%llu", &x);
      }
    }
    
    anns.resize(N);
    for (int u = 0; u < N; ++u) {
      int dim = 0;
      U basis[E];
      for (const U x : X[u]) {
        U y = x;
        for (int i = 0; i < dim; ++i) {
          chmin(y, y ^ basis[i]);
        }
        if (y) {
          for (int i = 0; i < dim; ++i) {
            chmin(basis[i], basis[i] ^ y);
          }
          basis[dim++] = y;
        }
      }
      // triangular
      int bsrs[E];
      U used = 0ULL;
      for (int i = 0; i < dim; ++i) {
        bsrs[i] = bsr(basis[i]);
        used |= 1ULL << bsrs[i];
      }
      anns[u].init();
      for (int e = 0; e < E; ++e) if (!(used & 1ULL << e)) {
        U z = 1ULL << e;
        for (int i = 0; i < dim; ++i) if (basis[i] & 1ULL << e) {
          z |= 1ULL << bsrs[i];
        }
        anns[u].add(0, z);
      }
    }
    
    ForestDP<Data> f(N);
    for (int u = 1; u < N; ++u) {
      f.ae(P[u], u);
    }
    f.run();
    
    for (int u = 0; u < N; ++u) {
      const U ans = f.tot[u].solve();
      printf("%llu\n", ans);
    }
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

2
1
2 2 3
2 1 1

output:

4
2

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 2ms
memory: 3672kb

input:

5
1 2 2 3
3 83 75 58
4 125 124 58 16
4 39 125 71 112
3 69 66 5
4 48 73 69 6

output:

171
125
183
142
243

result:

ok 5 lines

Test #3:

score: 0
Accepted
time: 1ms
memory: 3664kb

input:

2
1
0
0

output:

0
0

result:

ok 2 lines

Test #4:

score: 0
Accepted
time: 146ms
memory: 5420kb

input:

500
1 2 3 2 1 2 6 2 4 6 6 10 7 12 7 9 8 10 12 20 12 19 15 24 25 23 25 22 29 29 28 26 31 25 34 31 35 33 39 37 36 42 37 37 41 43 42 46 45 45 49 52 53 50 46 50 49 52 58 57 57 61 57 59 56 65 63 59 66 65 63 70 70 68 72 71 73 72 72 76 72 75 80 76 76 82 83 80 89 89 91 85 85 90 89 89 89 92 93 91 92 93 98 96...

output:

18434153946472599289
17931933346714042066
17916198204903720383
17916198204176061148
17931933346710961779
18445169471807930489
17931926407666058065
18445169471807930348
17931933346714042064
17916198204176061019
18445169471807930488
18446738828973977865
17916198204176061018
17931926407666058064
184467...

result:

ok 500 lines

Test #5:

score: -100
Time Limit Exceeded

input:

49999
1 1 3 1 1 5 2 4 1 8 7 6 3 13 4 12 12 1 19 8 2 16 23 6 21 3 11 1 21 7 14 6 3 28 31 24 6 22 27 11 17 25 41 5 17 13 1 48 17 14 31 18 43 30 53 27 7 39 4 2 11 55 48 17 32 15 24 44 53 63 70 31 21 17 74 37 34 48 15 33 14 53 8 9 72 10 65 77 69 36 32 61 51 63 77 25 71 47 59 94 39 41 77 24 5 33 43 18 72...

output:

18446744063446965319
18316893942693974299
18446744073709548919
18355577725686532847
18446744073709551614
18446744073709551615
18446744073709551614
18446744073709551615
18446736549671322125
12348860911474380074
18446744072601433415
18446744073709551615
17335313836902106838
18446744073709551576
184467...

result: