답안 #1049160

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1049160 2024-08-08T14:23:04 Z Blagoj Spring cleaning (CEOI20_cleaning) C++17
35 / 100
80 ms 24916 KB
#include <bits/stdc++.h>

using namespace std;

#define endl '\n'
#define ll long long
#define all(x) (x).begin(), (x).end()

const int mxn = 1e5 + 100;

int cnt[mxn], prf[mxn][2], ans, tin[mxn], Time, dpt[mxn], nxt[mxn][19];
vector<int> g[mxn];

void dfs(int cur, int par = -1, int depth = 0) {
    if (par == -1) for (int i = 0; i < 19; i++) nxt[cur][i] = cur;
    else {
        nxt[cur][0] = par;
        for (int i = 1; i < 19; i++) nxt[cur][i] = nxt[nxt[cur][i - 1]][i - 1];
    }
    tin[cur] = Time++;
    dpt[cur] = depth;
    for (auto x : g[cur]) if (x != par) dfs(x, cur, depth + 1);
    if (g[cur].size() == 1) cnt[cur] = 1;
    for (auto x : g[cur]) if (x != par) cnt[cur] += cnt[x];
    if (par != -1) ans += 2 - (cnt[cur] % 2);
}

int LCA(int x, int y) {
    if (dpt[x] > dpt[y]) swap(x, y);
    for (int i = 18; i >= 0; i--) {
        if (dpt[y] - (1 << i) >= dpt[x]) {
            y = nxt[y][i];
        }
    }
    for (int i = 18; i >= 0; i--) {
        if (nxt[x][i] != nxt[y][i]) {
            x = nxt[x][i];
            y = nxt[y][i];
        }
    }
    if (x != y) x = nxt[x][0];
    return x;
}

void dfs1(int cur, int par) {
    prf[cur][0] = prf[par][0];
    prf[cur][1] = prf[par][1];
    prf[cur][cnt[cur] % 2]++;
    for (auto x : g[cur]) if (x != par) dfs1(x, cur);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, q;
    cin >> n >> q;
    for (int i = 0; i < n - 1; i++) {
        int f, t;
        cin >> f >> t;
        g[f].push_back(t);
        g[t].push_back(f);
    }
    int root = -1;
    for (int i = 1; i <= n; i++) {
        if (g[i].size() > 1) {
            root = i;
            break;
        }
    }
    dfs(root);
    dfs1(root, root);
    int leafs = 0;
    for (int i = 1; i <= n; i++) leafs += g[i].size() == 1;
    vector<int> sum(n + 1), par(n + 1);
    while (q--) {
        int sz;
        cin >> sz;
        vector<int> nodes(sz);
        for (int i = 0; i < sz; i++) cin >> nodes[i];
        sort(all(nodes), [&] (int a, int b) {
            return tin[a] < tin[b];
        });
        int total = leafs + sz;
        for (int i = 0; i < sz; i++) {
            if (i == 0 || nodes[i] != nodes[i - 1]) {
                if (g[nodes[i]].size() == 1) {
                    total--;
                    sum[nodes[i]]--;
                }
            }
        }
        vector<int> v;
        for (int i = 0; i < sz; i++) {
            v.push_back(nodes[i]);
            if (i) v.push_back(LCA(v.back(), nodes[i]));
        }
        sort(all(v));
        v.erase(unique(all(v)), v.end());
        sort(all(v), [&] (int a, int b) {
            return tin[a] < tin[b];
        });
        vector<int> s = {root};
        for (int i = 0; i < v.size(); i++) {
            while (LCA(s.back(), v[i]) != s.back()) s.pop_back();
            par[v[i]] = s.back();
            s.push_back(v[i]);
        }
        for (int i = 0; i < sz; i++) sum[nodes[i]]++;
        for (int i = v.size() - 1; i >= 0; i--) {
            if (v[i] == root) continue;
            sum[par[v[i]]] += sum[v[i]];
        }
        int newAns = ans + sz;
        for (int i = 0; i < v.size(); i++) {
            if (sum[v[i]] % 2 == 1) {
                ll c0 = prf[v[i]][0] - prf[par[v[i]]][0];
                ll c1 = prf[v[i]][1] - prf[par[v[i]]][1];
                newAns -= c0;
                newAns += c1;
            }
        }
        if (total % 2 == 1) cout << -1 << endl;
        else cout << newAns << endl;
        for (auto x : v) sum[x] = 0;
    }
}

Compilation message

cleaning.cpp: In function 'int main()':
cleaning.cpp:103:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  103 |         for (int i = 0; i < v.size(); i++) {
      |                         ~~^~~~~~~~~~
cleaning.cpp:114:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  114 |         for (int i = 0; i < v.size(); i++) {
      |                         ~~^~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 4696 KB Output is correct
2 Incorrect 42 ms 6740 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 6576 KB Output is correct
2 Correct 19 ms 6620 KB Output is correct
3 Correct 21 ms 17364 KB Output is correct
4 Correct 47 ms 15740 KB Output is correct
5 Correct 59 ms 19288 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 7120 KB Output is correct
2 Correct 16 ms 7152 KB Output is correct
3 Correct 36 ms 24916 KB Output is correct
4 Correct 58 ms 24780 KB Output is correct
5 Correct 25 ms 22876 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 33 ms 7180 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 34 ms 14136 KB Output is correct
2 Incorrect 58 ms 13912 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 71 ms 18608 KB Output is correct
2 Correct 65 ms 21332 KB Output is correct
3 Correct 80 ms 21284 KB Output is correct
4 Correct 65 ms 20820 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 4696 KB Output is correct
2 Incorrect 42 ms 6740 KB Output isn't correct
3 Halted 0 ms 0 KB -