답안 #868227

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
868227 2023-10-30T22:56:49 Z Hakiers Spring cleaning (CEOI20_cleaning) C++17
18 / 100
560 ms 27664 KB
#include <bits/stdc++.h>
using namespace std;
const int BASE = 1 << 17;
vector<int> G[BASE];
int dp[BASE];
int sajz[BASE];
int LAZY[BASE << 1];
int TREE[BASE << 1][2];
int path_end[BASE];
int pre[BASE];
int parent[BASE];
int depth[BASE];
int tajm;
int n, q;

void push(int v, int l, int r){
	
	if(!LAZY[v]) return;
	LAZY[l] ^= LAZY[v];
	LAZY[r] ^= LAZY[v];
	
	swap(TREE[l][0], TREE[l][1]);
	swap(TREE[r][0], TREE[r][1]);
	LAZY[v] = 0;
}

void add(int a, int b, int v, int l, int r, int x){
	if(b < l || r < a) return;
	else if(l <= a && b <= r){
		TREE[v][x] = 1;
	}
	else{
		int mid = (a+b)/2;
		push(v, 2*v, 2*v+1);
		add(a, mid, 2*v, l, r, x);
		add(mid+1, b, 2*v + 1, l, r, x);
		TREE[v][0] = TREE[2*v][0] + TREE[2*v+1][0];
		TREE[v][1] = TREE[2*v][1] + TREE[2*v+1][1];
	}
}

void update(int a, int b, int v, int l, int r, int x){
	if(b < l || r < a) return;
	else if(l <= a && b <= r){
		swap(TREE[v][0], TREE[v][1]);
		LAZY[v] ^= x;
	}
	else{
		int mid = (a+b)/2;
		push(v, 2*v, 2*v+1);
		update(a, mid, 2*v, l, r, x);
		update(mid +1, b, 2*v+1, l, r, x);
		TREE[v][0] = TREE[2*v][0] + TREE[2*v+1][0];
		TREE[v][1] = TREE[2*v][1] + TREE[2*v+1][1];
	}
}

pair<int, int> query(int a, int b, int v, int l, int r){
	if(b < l || r < a) return {0, 0};
	else if(l <= a && b <= r){
		return {TREE[v][0], TREE[v][1]};
	}
	else{
		int mid = (a+b)/2;
		push(v, 2*v, 2*v+1);
		
		pair<int, int> p1 = query(a, mid, 2*v, l, r);
		pair<int, int> p2 = query(mid+1, b, 2*v+1, l, r);
		
		return {p1.first+p2.first, p1.second+p2.second};
	}
}

void dfs_size(int v, int p){
	sajz[v] = 1;
	for(auto u : G[v]){
		if(u == p) continue;
		dfs_size(u, v);
		sajz[v] += sajz[u];
	}
}


void hld(int v, int p){
	pre[v] = ++tajm;
	parent[v] = p;
	depth[v] = depth[p] + 1;
	int maxpath = 0;
	for(auto u : G[v])
		if(u != p && sajz[u] > sajz[maxpath]) maxpath = u;
		
	
	if(maxpath){
		path_end[maxpath] = path_end[v];
		hld(maxpath, v);
	}
	
	for(auto u : G[v]){
		if(u == p || u == maxpath) continue;
		path_end[u] = u;
		hld(u, v);
	}
}

void dfs_dp(int v, int p){
	if(G[v].size() == 1)
		dp[v] = 1;
		
	for(auto u : G[v]){
		if(u == p) continue;
		dfs_dp(u, v);
		dp[v] += dp[u];
	}
	
	add(0, BASE-1, 1, pre[v], pre[v], (dp[v]&1));
}


void no(){
	cout << "-1\n";
}

void yes(int howadd){
	pair<int, int> query2 = query(0, BASE-1, 1, pre[1]+1, tajm);
	howadd += query2.first *2;
	howadd += query2.second;
	
	cout << howadd << "\n";
}

void zmien(int u, int v){

	if(depth[u] < depth[v]) swap(u, v);
	
	while(path_end[u] != path_end[v]){
		update(0, BASE-1, 1, pre[path_end[u]], pre[u], 1);
		u = parent[u];
	}
	
	update(0, BASE-1, 1, pre[v], pre[u], 1);

}

void solve(){
	multiset<int> nodes;
	set<int> nodesS;
	vector<int> zmiany;
	int D;
	cin >> D;
	
	for(int i = 1; i <= D; i++){
		int v;
		cin >> v;
		nodes.insert(v);
		nodesS.insert(v);
	}
	
	int howadd = 0;
	for(auto v : nodesS){
		int countv = nodes.count(v);
		howadd += countv;
		if(G[v].size() == 1 && !(countv&1)){
			//cout << "v:" << v << "count" << countv << endl;
			zmien(1, v);
			zmiany.push_back(v);
		}
		else if(G[v].size() > 1 && countv&1){
			zmien(1, v);
			zmiany.push_back(v);
		}
	}
	
	pair<int, int> query1 = query(0, BASE-1, 1, pre[1], pre[1]);
	
	if(!query1.first) no();
	else yes(howadd);
	
	for(auto v : zmiany)
		zmien(1, v);
	
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> q;
	for(int i = 1; i < n; i++){
		int a, b;
		cin >> a >> b;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	
	dfs_size(1, 1);
	hld(1, 1);
	dfs_dp(1, 1);
	
	while(q--)
		solve();

}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 7260 KB Output is correct
2 Incorrect 167 ms 8880 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 31 ms 11352 KB Output is correct
2 Correct 32 ms 11800 KB Output is correct
3 Correct 40 ms 13768 KB Output is correct
4 Correct 110 ms 18892 KB Output is correct
5 Correct 100 ms 20912 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 32 ms 12124 KB Output is correct
2 Correct 32 ms 12372 KB Output is correct
3 Correct 57 ms 21164 KB Output is correct
4 Correct 122 ms 27664 KB Output is correct
5 Correct 49 ms 19820 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 560 ms 9244 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 191 ms 10916 KB Output is correct
2 Incorrect 280 ms 11172 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 310 ms 12760 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 7260 KB Output is correct
2 Incorrect 167 ms 8880 KB Output isn't correct
3 Halted 0 ms 0 KB -