QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#118873#5445. Vulpeculahos_lyricRE 1ms3744kbC++146.6kb2023-07-04 14:44:272023-07-04 14:44:28

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 14:44:28]
  • 评测
  • 测评结果:RE
  • 用时:1ms
  • 内存:3744kb
  • [2023-07-04 14:44:27]
  • 提交

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;

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

// https://qoj.ac/problem/5445
// given basis of two spaces, returns nonzero when their intersection increases
struct Intersection {
  // len = dim(their sum)
  int len;
  U as[E], bs[E];
  Intersection() : len(0) {}
  U add(U a, U b) {
    for (int i = 0; i < len; ++i) if (chmin(a, a ^ as[i])) b ^= bs[i];
    if (a) {
      as[len] = a; bs[len] = b; ++len; return 0;
    } else {
      return b;
    }
  }
  U add0(U a) { return add(a, 0); }
  U add1(U a) { return add(a, a); }
};
Intersection I;

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

  // identity: full space
  void init() {
    len = E;
    for (int e = 0; e < E; ++e) ps[e] = make_pair(N - 1, 1ULL << e);
  }
  void pull(const Data &a, const Data &b) {
    len = 0;
    I.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))) {
        const U y = I.add0(a.ps[i].second);
        if (y) ps[len++] = make_pair(a.ps[i].first, y);
        ++i;
      } else {
        const U y = I.add1(b.ps[j].second);
        if (y) ps[len++] = make_pair(b.ps[j].first, y);
        ++j;
      }
    }
// cerr<<"a = ";pv(a.ps,a.ps+a.len);
// cerr<<"b = ";pv(b.ps,b.ps+b.len);
// cerr<<"  -> ";pv(ps,ps+len);
  }
  void up(int u) {
    const Data a = *this;
    len = 0;
    I.len = 0;
    for (const U x : X[u]) {
      I.add0(x);
    }
    for (int i = 0; i < a.len; ++i) {
      const U y = I.add1(a.ps[i].second);
      if (y) ps[len++] = make_pair(min(1 + a.ps[i].first, N - 1), y);
    }
    for (const U x : X[u]) {
      U y = x;
      for (int i = 0; i < len; ++i) chmin(y, y ^ ps[i].second);
      if (y) ps[len++] = make_pair(0, y);
    }
// cerr<<"up "<<u<<" "<<X[u]<<endl;
// cerr<<"  a = ";pv(a.ps,a.ps+a.len);
// cerr<<"  -> ";pv(ps,ps+len);
  }

  U solve() const {
// pv(ps,ps+len);
    U ans = 0;
    int d = N - 1;
    U now = 0;
    for (int i = 0; i < len; ++i) {
      ans += (d - ps[i].first) * now;
      d = ps[i].first;
      chmax(now, now ^ ps[i].second);
    }
    ans += (d - (-1)) * now;
    return ans;
  }
};

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);
      }
    }
    
    int dim;
    U basis[E];
    for (int u = 0; u < N; ++u) {
      dim = 0;
      for (const U x : X[u]) {
        U y = x;
        for (int i = 0; i < dim; ++i) {
          chmin(y, y ^ basis[i]);
        }
        if (y) {
          basis[dim++] = y;
        }
      }
      X[u] = vector<U>(basis, basis + dim);
    }
    
    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;
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3684kb

input:

2
1
2 2 3
2 1 1

output:

4
2

result:

ok 2 lines

Test #2:

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

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: 0ms
memory: 3668kb

input:

2
1
0
0

output:

0
0

result:

ok 2 lines

Test #4:

score: -100
Runtime Error

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:


result: