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;
#define int long long
#define sz(x) (int)(x.size())
const int LOG=25;
int n, q;
vector<vector<int>> adj;
vector<int> depth;
vector<vector<int>> up;
vector<vector<int>> graph;
map<int, int> mp;
vector<int> prefix;
vector<int> parity;
vector<pair<int, int>> isin;
int cntleaf=0, tot=0;
int ans=0;
int begining=0;
bool sortt(int a, int b) {return isin[a].first<isin[b].first;}
void dfsdepth(int s, int lst, int &act) {
isin[s].first=act++;
if (adj[s].size()==1) prefix[s]++;
for (auto u: adj[s]) {
if (u==lst) continue;
depth[u]=depth[s]+1;
up[u][0]=s;
for (int i=1; i<LOG; i++) {
up[u][i]=up[ up[u][i-1] ][i-1];
}
dfsdepth(u, s, act);
prefix[s]+=prefix[u];
}
isin[s].second=act++;
return;
}
void dfsparity(int s, int lst=-1) {
for (auto u: adj[s]) {
if (u==lst) continue;
parity[u]=parity[s]+(prefix[u]+1)%2;
dfsparity(u, s);
}
if (lst==-1) tot+=n-1;
else tot+=(prefix[s]+1)%2;
return;
}
int dfstot(int s, int lst) {
int comp=mp[s];
for (auto u: graph[s]) {
comp+=dfstot(u, s);
}
//if (sz(adj[s])<2) comp++;
if (comp%2==1) {
int temp=parity[s], d=depth[s];
if (lst>=0) temp-=parity[lst], d-=depth[lst];
ans-=temp;
ans+=d-temp;
}
//if (sz(adj[s])<2) comp--;
return comp;
}
int lca(int a, int b) {
if (depth[a]<depth[b]) swap(a, b);
for (int i=LOG-1; i>=0; i--) {
if (depth[a]-depth[b] >= (1<<i)) {
a=up[a][i];
}
}
if (a==b) return a;
for (int i=LOG-1; i>=0; i--) {
if (up[a][i]!=up[b][i]) {
a=up[a][i];
b=up[b][i];
}
}
return up[a][0];
}
int ALLPROBLEM() {
int lst=cntleaf;
while(q--) {
cntleaf=lst;
int d; cin >> d;
mp.clear();
for (int i=0; i<d; i++) {
int u; cin >> u, u--;
if (sz(adj[u])>1 || mp[u]) {
cntleaf++;
} else mp[u]++;
mp[u]++;
}
if (cntleaf%2==1) {
cout << -1 << endl;
continue;
}
vector<int> change;
for (auto u: mp) {
if (u.second&1) change.push_back(u.first);
}
sort(change.begin(), change.end(), sortt);
set<int> L;
for (int i=0; i< sz(change); i++) {
L.insert(change[i]);
if (i!=0) L.insert(lca(change[i], change[i-1]));
}
vector<int> vec;
for (auto u=L.begin(); u!=L.end(); u++) {
vec.push_back(*u);
}
sort(vec.begin(), vec.end(), sortt);
stack<int> act;
if (!vec.empty() && vec[0]!=begining) act.push(begining);
for (auto u: vec) {
while (!act.empty() && isin[act.top()].second<isin[u].first) act.pop();
if (!act.empty() && act.top()!=u) graph[act.top()].push_back(u);
act.push(u);
}
ans=tot+d;
if (!vec.empty()) dfstot(vec[0], begining);
cout << ans << endl;
for (auto u: vec) graph[u].clear();
graph[begining].clear();
}
return 0;
}
int solve() {
cin >> n >> q;
adj.resize(n);
graph.resize(n);
up.resize(n, vector<int> (LOG, 0));
depth.resize(n, 0);
prefix.resize(n, 0);
parity.resize(n, 0);
isin.resize(n);
for (int i=0; i<n-1; i++) {
int u, v; cin >> u >> v;
u--, v--;
adj[u].push_back(v);
adj[v].push_back(u);
}
for (auto u: adj) if (sz(u)==1) cntleaf++;
int temp=0;
begining=0;
dfsdepth(begining, -1, temp);
dfsparity(begining);
return ALLPROBLEM();
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
solve();
return 0;
}
# | 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... |