Submission #1283449

#TimeUsernameProblemLanguageResultExecution timeMemory
1283449huyngodzzSpring cleaning (CEOI20_cleaning)C++20
100 / 100
324 ms18968 KiB
///huynhocute123///
#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define pii pair<int,int>
#define piii pair<int,pair<int,int>>
#define pb push_back
#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define REP(i, a, b) for(int i = b; i >= a; --i)
#define ALL(v) v.begin(),v.end()
#define inp(name) if(fopen(name, "r")) freopen(name, "r", stdin);
#define out(name) if(fopen(name, "w")) freopen(name, "w", stdout);
//random_device rd;
//mt19937 rng(rd());
//#pragma GCC optimize ("O3")
//#pragma GCC optimize ("unroll-loops")
//#pragma GCC target("popcnt")
//#define int long long
const int MAX = 1e9+9;
const long long  MAXLL = 1e18+9;
const double pi = 3.14159265358979323846;
const double rad = 3.14159265358979323846 /180;
bool minimize(int &u, int v){
    if(v < u){
        u = v;
        return 1;
    }
    return 0;
}
bool maximize(int &u, int v){
    if(v > u){
        u = v;
        return 1;
    }
    return 0;
}
bool maximizell(long long &u, long long v){
    if(v > u){
        u = v;
        return 1;
    }
    return 0;
}
bool minimizell(long long &u, long long v){
    if(v < u){
        u = v;
        return 1;
    }
    return 0;
}
const int  mod = 1e9 + 7;
inline int fastPow(int a, int n){
    if(n == 0) return 1;
    int t = fastPow(a, n >> 1);
    t = 1ll * t * t % mod;
    if(n & 1) t = 1ll * t * a % mod;
    return t;
}
const int maxN = 1e5 + 99 ;
int n, q;
vector<int> e[maxN];
bool leaf[maxN], ok[maxN];
int sz[maxN] ,par[maxN];
int head[maxN] , chain[maxN] , pos[maxN] , ar[maxN], c_chain, c_pos;
int Count_leaf[maxN];
void pre(int u ,int p){
//    cout << u << '\n';
    sz[u] = 1;
    for(auto x : e[u]){
        if(x == p)continue;
        par[x] = u;
        pre(x ,u);
        sz[u] = sz[u] + sz[x];
        Count_leaf[u] += Count_leaf[x];
    }
    if(e[u].size() == 1){
        Count_leaf[u]++;
        leaf[u] = 1;
        ok[u] = 1;
    }
}
void hld(int u ,int p){
    if(!head[c_chain])head[c_chain] = u;
    chain[u] = c_chain;
    pos[u] = ++c_pos;
    ar[c_pos] = u;
    int nxt = 0;
    for(auto x : e[u]){
        if(x == p)continue;
        if(nxt == 0 || sz[x] > sz[nxt])nxt = x;
    }
    if(nxt)hld(nxt, u);
    for(auto x : e[u]){
        if(x == p || x == nxt)continue;
        ++c_chain;
        hld(x, u);
    }
}
pii st[4 * maxN];
int lazy[4 * maxN];
void push(int id){
    if(lazy[id] == 0)return;
    st[id << 1].F = st[id << 1].S - st[id << 1].F;
    st[id << 1 | 1].F = st[id << 1 | 1].S - st[id << 1 | 1].F;
    lazy[id << 1]  ^= 1;
    lazy[id << 1 | 1]  ^= 1;
    lazy[id] = 0;
}
pii Merge(pii X , pii Y){
    return make_pair(X.F + Y.F , X.S + Y.S);
}
void build(int id, int l ,int r){
    if(l == r){
        st[id] = make_pair( (Count_leaf[ar[l]] & 1 ) ? 1 : 2 , 3);
//        cerr << l << " " << ar[l] << " " <<Count_leaf[ar[l]] <<" " <<  st[id].F  << '\n';
        return;
    }
    int mid = (l + r)/2;
    build(id << 1, l ,mid);
    build(id << 1 | 1,mid + 1, r);
    st[id] = Merge(st[id << 1] ,st[id << 1 | 1]);
}
void upd(int id ,int l ,int r ,int u ,int v){
    if(v < l || u > r)return;
    if(u <= l && r <= v){
        st[id].F = st[id].S - st[id].F;
        lazy[id] ^= 1;
        return;
    }
    int mid = (l +r)/2;
    push(id);
    upd(id << 1, l ,mid , u ,v);
    upd(id << 1 | 1,mid + 1, r , u ,v);
    st[id] = Merge(st[id << 1 ] ,st[id << 1 | 1]);
}
pii get(int id, int l ,int r ,int u,int v){
    if(v  < l || u > r)return make_pair(0 , 0);
    if(u <= l && r <= v)return st[id];
    int mid = (l + r)/2;
    push(id);
    return Merge(get(id << 1  ,l , mid , u ,v) , get(id << 1 | 1, mid + 1, r, u , v));
}
int path_upd(int u ,int v){
    int delta = 0;
    while(1){
        if(chain[u] != chain[v]){
            if(chain[u] < chain[v])swap(u ,v);
            int top = head[chain[u]];
            pii X = get(1, 1, n , pos[top], pos[u]);
//            cout << X.F << " " << X.S << '\n';
            delta += -2 * X.F + X.S;
            upd(1, 1, n , pos[top], pos[u]);
            u = par[top];
        }else{
            int l = min(pos[u] , pos[v]);
            int r = max(pos[u] , pos[v]);
            pii X = get(1, 1, n , l + 1, r );
//            cout << X.F << " " << X.S << '\n';

            delta += -2 * X.F + X.S;
            upd(1, 1, n , l + 1, r);
            break;
        }
    }
//    cout << delta << " ";
    return delta;
}
inline void solve(){
    cin >> n >> q;
    FOR(i, 2 ,n){
        int u ,v ;cin >> u >> v;
        e[u].pb(v);
        e[v].pb(u);
    }
    pre(1, 0);
    c_chain = 1;
    c_pos = 0;
    hld(1, 0);
    build(1, 1 ,n);
//    cout << path_upd(4, 1);
    FOR(xccx ,1 , q){
        vector<int> ar;
        int sz;cin >> sz;
        FOR(i, 1 ,sz){
            int x; cin >> x;
            ar.pb(x);
        }

        int cur_leaf = Count_leaf[1];
        for(auto x : ar){
            if(leaf[x] == 0)++cur_leaf;
            else{
                if(ok[x])ok[x] = 0;
                else ++cur_leaf;
            }
        }
        for(auto x : ar)ok[x] = 1;
        if(cur_leaf & 1){
            cout << -1 << '\n';
            continue;
        }
        int cur_ans = get(1, 1, n, 2,  n).F;
        vector<int> change;
        for(auto x : ar){
            if(leaf[x]){
                if(ok[x])ok[x] = 0;
                else{
                    change.pb(x);
                    cur_ans += path_upd(x , 1);
                }

            }else {
                    change.pb(x);
                    cur_ans += path_upd(x , 1);
            }

        }
        for(auto x : change)path_upd(x ,1);
        cout << cur_ans + sz << '\n';
        cerr << cur_ans + sz << '\n';
        for(auto x : ar)ok[x] = 1;
//        cout << get(1, 1, n, 2, n).F << '\n';
    }
//    cout << get(1, 1, n , pos[6] ,pos[6]) <<'\n';
//    cout << get(1, 1, n ,2 , n) << '\n';
//    cout << st[1].F;
}
signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    #define NAME "task"
    if(fopen(NAME".inp", "r")){
        freopen(NAME".inp", "r" ,stdin);
        freopen(NAME".out", "w" ,stdout);
    }
    int tc = 1;
   // cin >> tc;
    while( tc-- )solve();
    cerr << '\n' << "Time elapsed: " << (1.0 * clock() / CLOCKS_PER_SEC) << " s\n" ;


}

Compilation message (stderr)

cleaning.cpp: In function 'int main()':
cleaning.cpp:235:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  235 |         freopen(NAME".inp", "r" ,stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
cleaning.cpp:236:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  236 |         freopen(NAME".out", "w" ,stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...