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;
const int N=2e5;
vector<vector<int>> g(N);
vector<int> tin(N), c(N), tout(N);
int leafs;
template <class T>
struct RMQ { // 0-based
vector<vector<T>> rmq;
T kInf = numeric_limits<T>::max();
void build(const vector<T>& V) {
int n = V.size(), on = 1, dep = 1;
while (on < n) on *= 2, ++dep;
rmq.assign(dep, V);
for (int i = 0; i < dep - 1; ++i)
for (int j = 0; j < n; ++j) {
rmq[i + 1][j] = min(rmq[i][j], rmq[i][min(n - 1, j + (1 << i))]);
}
}
T query(int a, int b) { // [a, b)
if (b <= a) return kInf;
int dep = 31 - __builtin_clz(b - a); // log(b - a)
return min(rmq[dep][a], rmq[dep][b - (1 << dep)]);
}
};
struct LCA { // 0-based
vector<int> depth;
vector<pair<int, int>> linear;
RMQ<pair<int, int>> rmq;
int timer = 0;
LCA() {}
LCA(int n): depth(n), linear(2 * n) {}
void dfs(int node, int par) {
linear[timer] = {depth[par]+1, node};
tin[node] = timer++;
depth[node] = depth[par]+1;
for (auto vec : g[node])
if (vec!=par) {
dfs(vec, node);
c[node]+=c[vec];
linear[timer++] = {depth[node], node};
}
if(g[node].size()==1) c[node]++, leafs++;
tout[node] = timer;
}
void build(int root) {
dfs(root, 0);
rmq.build(linear);
}
int query(int a, int b) {
a = tin[a], b = tin[b];
return rmq.query(min(a, b), max(a, b) + 1).second;
}
int dist(int a, int b) {
return depth[a] + depth[b] - 2 * depth[query(a, b)];
}
};
int32_t main(){
ios_base::sync_with_stdio(false); cin.tie(0);
int n, q; cin >> n >> q;
vector<array<int, 2>> count(n);
int root=0;
for(int i =0; i<n-1; i++){
int x, y; cin >> x >> y;
x--; y--;
g[x].push_back(y);
g[y].push_back(x);
if(g[x].size()>1) root = x;
if(g[y].size()>1) root = y;
}
LCA lca(n);
lca.build(root);
int ans = 0;
auto dfs2=[&](int v, int p, auto&& dfs2)->void{
//cout<<v+1<<" "<<c[v]<<"\n";
if(c[v] %2) count[v][1]++;
else count[v][0]++, ans++;
for(auto i: g[v]){
if(i!=p){
count[i][0]+=count[v][0];
count[i][1]+=count[v][1];
dfs2(i, v, dfs2);
}
}
};
dfs2(root, root, dfs2) ;
int tmpans = ans, tmpleafs=leafs;
while(q--){
int d; cin >> d;
vector<int> ar(d),a, up;
for(auto &i: ar) cin >> i, i--;
sort(ar.begin(), ar.end(), [&](int x, int y){
return tin[x] < tin[y];
});
int k=1;
for(int i=1; i<d; i++){
if(ar[i]==ar[i-1])k++;
else{
if(g[ar[i-1]].size()==1){
leafs+=k-1;
if(k%2==0) a.push_back(ar[i-1]);
k = 1;
}
else{
leafs+=k;
if(k%2==1) a.push_back(ar[i-1]);
k=1;
}
}
}
if(g[ar[d-1]].size()==1){
leafs+=k-1;
if(k%2==0) a.push_back(ar[d-1]);
}
else{
leafs+=k;
if(k%2==1) a.push_back(ar[d-1]);
}
up = a;
if(up.size()){
for(int i=0; i<a.size()-1; i++){
up.push_back(lca.query(a[i], a[i+1]));
}
sort(up.begin(), up.end(), [&](int x, int y){
return tin[x] < tin[y];
});
vector<int> upp;
for(int i=0; i<up.size(); i++){
if(i==0||up[i]!=up[i-1]) upp.push_back(up[i]);
}
up=upp;
upp.clear();
if(up.size()){
stack<int> st;
st.push(0);
vector<int> p(up.size()), v(up.size()), s(up.size());
vector<vector<int>> adj(up.size());
vector<int> aa(up.size());
sort(up.begin(), up.end(), [&](int x, int y){
return tin[x] < tin[y];
});
for(int i=1; i<up.size(); i++) {
while(st.size() && tout[up[st.top()]] < tin[up[i]]){
st.pop();
}
if(st.size())
adj[st.top()].push_back(i), aa[i]++, p[i]=st.top();
else p[i]=i;
st.push(i);
}
auto dfsa=[&](int ve, auto&&dfsa)->void{
for(auto i: adj[ve]){
dfsa(i, dfsa), v[ve]+=v[i];
}
};
int pos=0;
for(int l=0; l<a.size(); l++){
while(pos<up.size()&&up[pos]!=a[l]) pos++;
if(pos<up.size()&&up[pos]==a[l]) v[pos]++;
}
for(int i=0; i<up.size(); i++){
if(aa[i]==0) dfsa(i, dfsa);
}
for(int i=0; i<up.size(); i++){
if(p[i]==i){
auto x = count[up[i]];
if(v[i]%2){
ans-=x[0]; ans+=x[1];
}
}
else if(v[i]%2){
auto x=count[up[i]], y=count[up[p[i]]];
x[0]-=y[0];
x[1]-=y[1];
ans-=x[0]; ans+=x[1];
}
}
}
}
if((leafs%2)!=0) cout<<-1<<"\n";
else cout<<ans-1+d+n-1<<"\n";
ans=tmpans; leafs=tmpleafs;
}
}
Compilation message (stderr)
cleaning.cpp: In function 'int32_t main()':
cleaning.cpp:144:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
144 | for(int i=0; i<a.size()-1; i++){
| ~^~~~~~~~~~~
cleaning.cpp:155:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
155 | for(int i=0; i<up.size(); i++){
| ~^~~~~~~~~~
cleaning.cpp:174:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
174 | for(int i=1; i<up.size(); i++) {
| ~^~~~~~~~~~
cleaning.cpp:191:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
191 | for(int l=0; l<a.size(); l++){
| ~^~~~~~~~~
cleaning.cpp:192:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
192 | while(pos<up.size()&&up[pos]!=a[l]) pos++;
| ~~~^~~~~~~~~~
cleaning.cpp:193:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
193 | if(pos<up.size()&&up[pos]==a[l]) v[pos]++;
| ~~~^~~~~~~~~~
cleaning.cpp:196:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
196 | for(int i=0; i<up.size(); i++){
| ~^~~~~~~~~~
cleaning.cpp:202:32: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
202 | for(int i=0; i<up.size(); i++){
| ~^~~~~~~~~~
# | 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... |