This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
template <size_t L>
struct Segtree
{
int t[L << 1];
bitset<L << 1> lzy;
void set(size_t i, int x) { t[i + L] = x; }
void build()
{
for (size_t i = L - 1; i; --i)
t[i] = t[i << 1] + t[i << 1 | 1];
}
void propagate(size_t k, size_t a, size_t b)
{
if (lzy[k])
{
lzy[k << 1] = !lzy[k << 1];
lzy[k << 1 | 1] = !lzy[k << 1 | 1];
t[k << 1] = (b - a + 1) / 2 - t[k << 1];
t[k << 1 | 1] = (b - a + 1) / 2 - t[k << 1 | 1];
lzy[k] = 0;
}
}
void flip(size_t i, size_t j, size_t k = 1, size_t a = 0, size_t b = L - 1)
{
if (b < i || a > j)
return;
if (i <= a && b <= j)
{
lzy[k] = !lzy[k];
t[k] = b - a + 1 - t[k];
}
else
{
propagate(k, a, b);
flip(i, j, k << 1, a, (a + b) >> 1);
flip(i, j, k << 1 | 1, ((a + b) >> 1) + 1, b);
t[k] = t[k << 1] + t[k << 1 | 1];
}
}
int sum(size_t i, size_t j, size_t k = 1, size_t a = 0, size_t b = L - 1)
{
if (b < i || a > j)
return 0;
if (i <= a && b <= j)
return t[k];
propagate(k, a, b);
return sum(i, j, k << 1, a, (a + b) >> 1) + sum(i, j, k << 1 | 1, ((a + b) >> 1) + 1, b);
}
};
template <size_t N>
struct Hld
{
vector<size_t> g[N];
size_t root[N], parent[N], subtree_size[N], ind[N];
Segtree<N> tree;
void add_edge(size_t u, size_t v)
{
g[u].push_back(v);
g[v].push_back(u);
}
void build()
{
memset(parent, 255, sizeof parent);
find_heavy(0);
find_root(0);
init_segtree(0);
tree.build();
}
void find_heavy(size_t u)
{
subtree_size[u] = 1;
for (auto &v : g[u])
if (v != parent[u])
{
parent[v] = u;
find_heavy(v);
subtree_size[u] += subtree_size[v];
if (g[u][0] == parent[u] || subtree_size[v] > subtree_size[g[u][0]])
swap(v, g[u][0]);
}
}
size_t find_root(size_t u, size_t i = 0)
{
ind[u] = i++;
for (auto const &v : g[u])
if (v != parent[u])
{
root[v] = v == g[u][0] ? root[u] : v;
i = find_root(v, i);
}
return i;
}
bool init_segtree(size_t u)
{
bool leaf_parity = g[u].size() == 1;
for (auto const &v : g[u])
if (v != parent[u])
leaf_parity ^= init_segtree(v);
tree.set(ind[u], leaf_parity);
return leaf_parity;
}
void update_root_path(size_t u)
{
while (u != SIZE_MAX)
{
tree.flip(ind[root[u]], ind[u]);
u = parent[root[u]];
}
}
};
constexpr size_t N = 1 << 17;
Hld<N> h;
size_t a[N];
bitset<N> no_leaf_anymore;
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
size_t n, q;
cin >> n >> q;
for (size_t i = 0; i < n - 1; ++i)
{
size_t u, v;
cin >> u >> v;
h.add_edge(u - 1, v - 1);
}
h.build();
size_t num_leafs = 0;
for (size_t i = 0; i < n; ++i)
num_leafs += h.g[i].size() == 1;
while (q--)
{
size_t d;
cin >> d;
for (size_t i = 0; i < d; ++i)
{
cin >> a[i], --a[i];
num_leafs += h.g[a[i]].size() > 1;
}
if (!(num_leafs & 1))
{
for (size_t i = 0; i < d; ++i)
if (h.g[a[i]].size() > 1 || no_leaf_anymore[a[i]])
h.update_root_path(a[i]);
else if (h.g[a[i]].size() == 1)
no_leaf_anymore[a[i]] = 1;
for (size_t i = 0; i < d; ++i)
no_leaf_anymore[a[i]] = 0;
cout << 2 * (n - 1) + d - h.tree.sum(0, n - 1) << '\n';
for (size_t i = 0; i < d; ++i)
if (h.g[a[i]].size() > 1 || no_leaf_anymore[a[i]])
h.update_root_path(a[i]);
else if (h.g[a[i]].size() == 1)
no_leaf_anymore[a[i]] = 1;
for (size_t i = 0; i < d; ++i)
no_leaf_anymore[a[i]] = 0;
}
else
{
cout << "-1\n";
}
for (size_t i = 0; i < d; ++i)
num_leafs -= h.g[a[i]].size() > 1;
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |