답안 #751169

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
751169 2023-05-31T07:05:24 Z inventiontime Spring cleaning (CEOI20_cleaning) C++17
37 / 100
285 ms 52928 KB
#include <bits/stdc++.h>
using namespace std;

#define int ll
#define endl '\n' //comment for interactive
#define fast_io ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

#define pb push_back
#define re resize
#define ff first
#define ss second

#define all(x) (x).begin(), (x).end()
#define all1(x) (x).begin()+1, (x).end()
#define loop(i, n) for(int i = 0; i < n; i++)
#define loop1(i, n) for(int i = 1; i <= n; i++)

#define print(x) cout << #x << ": " << x << endl << flush

typedef long long ll;
typedef vector<int> vi;
typedef array<int, 2> ii;
typedef array<int, 3> ti;
typedef vector<ii> vii;
typedef vector<ti> vti;
typedef vector<vi> vvi;
typedef priority_queue<int> pq;

template<class T> bool ckmin(T&a, T b) { bool B = a > b; a = min(a, b); return B; }
template<class T> bool ckmax(T&a, T b) { bool B = a < b; a = max(a, b); return B; }

const int inf = 1e17;
const int maxn = 1e5+5;

vi adj[maxn];
int tin[maxn];
int tout[maxn];
int lv[maxn];
int par[maxn][21];
int edge[maxn][21];
vi virt_adj[maxn];
ii virt_edge[maxn];
int virt_lv[maxn];
int timer = 1;
int total = 0;

ii operator+(ii l, ii r) { return {l[0]+r[0],l[1]+r[1]}; }
ii& operator+=(ii& l, ii r) { l = l + r; return l; }

bool is_leaf(int u) {
    return adj[u].size() == 1;
}

bool is_anc(int u, int v) {
    return tin[u] <= tin[v] and tout[v] <= tout[u];
}

int lca(int u, int v) {
    if(is_anc(u, v)) return u;
    if(is_anc(v, u)) return v;

    for(int j = 20; j >= 0; j--)
        if(!is_anc(par[u][j], v))
            u = par[u][j];
        
    return par[u][0];
}

void predfs(int u, int p) {
    tin[u] = timer++;
    par[u][0] = p;
    for(auto v : adj[u]) if(v != p) {
        predfs(v, u);
        lv[u] += lv[v];
    }
    if(is_leaf(u)) lv[u] += 1;
    if(u != p) total += (edge[u][0] = !(lv[u] & 1));
    tout[u] = timer;
}

bool comp(int a, int b) { return tin[a] < tin[b]; }

void solve() {

    int n, q;
    cin >> n >> q;
    loop1(i, n-1) {
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
        adj[v].pb(u);
    }

    predfs(1, 1);
    edge[1][0] = 0;
    loop1(j, 20) loop1(i, n) {
        par[i][j] = par[par[i][j-1]][j-1];
        edge[i][j] = edge[par[i][j-1]][j-1] + edge[i][j-1];
    }
    
    vi new_lv(n+1);
    while(q--) {

        int d; cin >> d;
        vi a(d);
        loop(i, d) {
            cin >> a[i];
            new_lv[a[i]]++;
        }

        vi b = a;
        sort(all(b), comp);
        b.erase(unique(all(b)), b.end());
        int cnt = b.size();
        loop(i, cnt-1) {
            b.pb(lca(b[i], b[i+1]));
        }
        sort(all(b), comp);
        b.erase(unique(all(b)), b.end());
        cnt = b.size();
        stack<int> st;
        st.push(b[0]);
        loop1(i, cnt-1) {
            while(!is_anc(st.top(), b[i])) 
                st.pop();
            int u = st.top();
            int v = b[i];

            for(int j = 20; j >= 0; j--)
                if(!is_anc(par[v][j], u)) {
                    virt_edge[b[i]] += (ii) {edge[v][j], 1 << j};
                    v = par[v][j];
                }
            
            if(!is_anc(v, u)) {
                virt_edge[b[i]] += (ii) {edge[v][0], 1};
                v = par[v][0];
            }

            virt_adj[u].pb(b[i]);
            st.push(b[i]);
        }

        int delta = 0;
        auto dfs = [&] (int u, auto dfs) -> void {
            if(new_lv[u])
                virt_lv[u] += new_lv[u] - is_leaf(u);
            for(auto v : virt_adj[u]) {
                dfs(v, dfs);
                virt_lv[u] += virt_lv[v];
            }

            if((virt_lv[u] & 1) and u != b[0]) {
                auto [x, y] = virt_edge[u];
                delta += y - 2*x;
            }
        };
        dfs(b[0], dfs);
        if((lv[1] + virt_lv[b[0]]) & 1) cout << -1 << endl;
        else cout << (n+d-1) + total + delta << endl;

        loop(i, cnt) {
            virt_adj[b[i]].clear();
            virt_edge[b[i]] = {0, 0};
            virt_lv[b[i]] = 0;
        }

        loop(i, d)
            new_lv[a[i]]--;

    }

}

signed main() {

    fast_io;

    int t = 1; //cin >> t;
    while(t--)
        solve();

    return 0;

}
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 4948 KB Output is correct
2 Incorrect 92 ms 14600 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 7992 KB Output is correct
2 Correct 20 ms 7912 KB Output is correct
3 Correct 93 ms 48268 KB Output is correct
4 Correct 111 ms 38100 KB Output is correct
5 Correct 149 ms 51188 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 23 ms 9308 KB Output is correct
2 Correct 23 ms 9260 KB Output is correct
3 Correct 123 ms 52928 KB Output is correct
4 Correct 154 ms 52368 KB Output is correct
5 Correct 117 ms 46976 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 15020 KB Output is correct
2 Incorrect 42 ms 13944 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 109 ms 33736 KB Output is correct
2 Correct 285 ms 33860 KB Output is correct
3 Correct 156 ms 19832 KB Output is correct
4 Correct 175 ms 33760 KB Output is correct
5 Correct 171 ms 33900 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 161 ms 48048 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 4948 KB Output is correct
2 Incorrect 92 ms 14600 KB Output isn't correct
3 Halted 0 ms 0 KB -