답안 #349025

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
349025 2021-01-16T10:55:31 Z dolphingarlic Spring cleaning (CEOI20_cleaning) C++14
100 / 100
183 ms 26208 KB
#include <bits/stdc++.h>
using namespace std;

int n, q;
vector<int> graph[100001];
int leaves[100001], tot_leaves = 0, bad = 0;
bool is_leaf[100001];
int tin[100001], tout[100001], timer = 0, anc[100001][18];

vector<int> vtree[100001];
int ans, bit[100001];
int a[100001], l_delta[100001];

void update(int pos, int val) { for (; pos <= n; pos += pos & -pos) bit[pos] += val; }

int query(int l, int r) {
    int res = 0;
    for (; r; r -= r & -r) res += bit[r];
    for (l--; l; l -= l & -l) res -= bit[l];
    return res;
}

void lca_dfs(int node, int parent = 0) {
    // LCA stuff
    tin[node] = ++timer;
    for (int i = 1; i < 18; i++) anc[node][i] = anc[anc[node][i - 1]][i - 1];
    // Check whether it's a leaf
    if (graph[node].size() == 1) {
        leaves[node] = 1;
        tot_leaves++;
        is_leaf[node] = true;
    }
    // DFS on children
    for (int i : graph[node]) if (i != parent) {
        anc[i][0] = node;
        lca_dfs(i, node);
        leaves[node] += leaves[i];
    }
    tout[node] = timer;
    // Set what happens when we toggle the parity
    if (leaves[node] & 1) update(tin[node], 1), update(tout[node] + 1, -1);
    else {
        update(tin[node], -1), update(tout[node] + 1, 1);
        bad++;
    }
}

bool is_ancestor(int u, int v) { return tin[u] <= tin[v] && tout[u] >= tout[v]; }

int lca(int u, int v) {
    if (is_ancestor(u, v)) return u;
    for (int i = 17; ~i; i--) if (anc[u][i] && !is_ancestor(anc[u][i], v)) u = anc[u][i];
    return anc[u][0];
}

void vtree_dfs(int node, int parent = 0) {
    for (int i : vtree[node]) if (i != parent) {
        vtree_dfs(i, node);
        l_delta[node] += l_delta[i];
    }
    ans += (l_delta[node] & 1) * query(tin[parent] + 1, tin[node]);
}

bool cmp(int u, int v) { return tin[u] < tin[v]; }

int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> q;
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) if (graph[i].size() > 1) {
        lca_dfs(i);
        break;
    }

    while (q--) {
        // Read query data and update original tree
        int d;
        cin >> d;
        vector<int> nodes;
        for (int i = 0; i < d; i++) {
            cin >> a[i];
            if (is_leaf[a[i]]) is_leaf[a[i]] = false;
            else {
                leaves[a[i]]++;
                tot_leaves++;
                l_delta[a[i]]++;
                nodes.push_back(a[i]);
            }
        }

        // Construct the virtual tree
        sort(nodes.begin(), nodes.end(), cmp);
        int m = nodes.size();
        for (int i = 1; i < m; i++) nodes.push_back(lca(nodes[i - 1], nodes[i]));
        sort(nodes.begin(), nodes.end(), cmp);
        nodes.erase(unique(nodes.begin(), nodes.end()), nodes.end());
        
        vector<int> stck;
        for (int i : nodes) {
            while (stck.size() > 1 && !is_ancestor(stck.back(), i)) {
                vtree[stck[stck.size() - 2]].push_back(stck.back());
                stck.pop_back();
            }
            stck.push_back(i);
        }
        while (stck.size() > 1) {
            vtree[stck[stck.size() - 2]].push_back(stck.back());
            stck.pop_back();
        }

        // Compute and output the answer
        if (tot_leaves & 1) cout << "-1\n";
        else {
            ans = n + d + bad - 2;
            if (stck.size()) vtree_dfs(stck[0]);
            cout << ans << '\n';
        }

        // Reset the original tree
        for (int i = 0; i < d; i++) {
            if (leaves[a[i]] == 1) is_leaf[a[i]] = true;
            else {
                leaves[a[i]]--;
                tot_leaves--;
            }
        }

        // Reset the vtree
        for (int i : nodes) {
            vtree[i].clear();
            l_delta[i] = 0;
        }
    }
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 5100 KB Output is correct
2 Correct 48 ms 7788 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 37 ms 6892 KB Output is correct
2 Correct 37 ms 6892 KB Output is correct
3 Correct 70 ms 17508 KB Output is correct
4 Correct 77 ms 15076 KB Output is correct
5 Correct 108 ms 18660 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 7532 KB Output is correct
2 Correct 48 ms 7532 KB Output is correct
3 Correct 76 ms 24940 KB Output is correct
4 Correct 134 ms 26208 KB Output is correct
5 Correct 66 ms 22892 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 50 ms 8576 KB Output is correct
2 Correct 25 ms 7660 KB Output is correct
3 Correct 16 ms 7532 KB Output is correct
4 Correct 23 ms 8192 KB Output is correct
5 Correct 19 ms 8300 KB Output is correct
6 Correct 39 ms 8428 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 78 ms 13420 KB Output is correct
2 Correct 95 ms 13292 KB Output is correct
3 Correct 61 ms 9452 KB Output is correct
4 Correct 109 ms 13548 KB Output is correct
5 Correct 103 ms 13292 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 130 ms 17896 KB Output is correct
2 Correct 146 ms 20588 KB Output is correct
3 Correct 158 ms 20736 KB Output is correct
4 Correct 142 ms 20076 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 5100 KB Output is correct
2 Correct 48 ms 7788 KB Output is correct
3 Correct 37 ms 6892 KB Output is correct
4 Correct 37 ms 6892 KB Output is correct
5 Correct 70 ms 17508 KB Output is correct
6 Correct 77 ms 15076 KB Output is correct
7 Correct 108 ms 18660 KB Output is correct
8 Correct 47 ms 7532 KB Output is correct
9 Correct 48 ms 7532 KB Output is correct
10 Correct 76 ms 24940 KB Output is correct
11 Correct 134 ms 26208 KB Output is correct
12 Correct 66 ms 22892 KB Output is correct
13 Correct 50 ms 8576 KB Output is correct
14 Correct 25 ms 7660 KB Output is correct
15 Correct 16 ms 7532 KB Output is correct
16 Correct 23 ms 8192 KB Output is correct
17 Correct 19 ms 8300 KB Output is correct
18 Correct 39 ms 8428 KB Output is correct
19 Correct 78 ms 13420 KB Output is correct
20 Correct 95 ms 13292 KB Output is correct
21 Correct 61 ms 9452 KB Output is correct
22 Correct 109 ms 13548 KB Output is correct
23 Correct 103 ms 13292 KB Output is correct
24 Correct 130 ms 17896 KB Output is correct
25 Correct 146 ms 20588 KB Output is correct
26 Correct 158 ms 20736 KB Output is correct
27 Correct 142 ms 20076 KB Output is correct
28 Correct 91 ms 12652 KB Output is correct
29 Correct 166 ms 21228 KB Output is correct
30 Correct 94 ms 18628 KB Output is correct
31 Correct 132 ms 26080 KB Output is correct
32 Correct 100 ms 13292 KB Output is correct
33 Correct 146 ms 18412 KB Output is correct
34 Correct 183 ms 21612 KB Output is correct
35 Correct 183 ms 21480 KB Output is correct