QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#118829 | #5445. Vulpecula | hos_lyric | TL | 146ms | 5420kb | C++14 | 7.1kb | 2023-07-04 13:20:45 | 2023-07-04 13:20:45 |
Judging History
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...