제출 #945535

#제출 시각아이디문제언어결과실행 시간메모리
945535berrSpring cleaning (CEOI20_cleaning)C++17
100 / 100
145 ms86608 KiB
#include <bits/stdc++.h>
using namespace std;
 
#define int long long
 

template <class T>
struct RMQ { // 0-based
  vector<vector<T>> rmq;
  T kInf = numeric_limits<T>::max();
  void build(const vector<T>& V) {
    int n = V.size(), on = 1, dep = 1;
    while (on < n) on *= 2, ++dep;
    rmq.assign(dep, V);
 
    for (int i = 0; i < dep - 1; ++i)
      for (int j = 0; j < n; ++j) {
        rmq[i + 1][j] = min(rmq[i][j], rmq[i][min(n - 1, j + (1 << i))]);
      }
  }
  T query(int a, int b) { // [a, b)
    if (b <= a) return kInf;
    int dep = 31 - __builtin_clz(b - a); // log(b - a)
    return min(rmq[dep][a], rmq[dep][b - (1 << dep)]);
  }
};

struct LCA { // 0-based
int n, root;
  vector<int> enter, depth, exxit;
  vector<vector<int>> G;
  vector<pair<int, int>> linear;
  RMQ<pair<int, int>> rmq;
  int timer = 0;
  LCA() {} 
  LCA(vector<vector<int>> g, int root)  {
    n = g.size();
    enter.resize(n, -1),
    exxit.resize(n, -1); 
    depth.resize(n);
    G=g;
    linear.resize(2 * n);

    build(root);
  }
  void dfs(int node, int dep) {
    linear[timer] = {dep, node};
    enter[node] = timer++;
    depth[node] = dep;
    for (auto vec : G[node])
    if (enter[vec] == -1) {
      dfs(vec, dep + 1);
      linear[timer++] = {dep, node};
    }
    exxit[node] = timer;
  }
  void add_edge(int a, int b) {
    G[a].push_back(b);
    G[b].push_back(a);
  }
  void build(int root) {
    dfs(root, 0);
    rmq.build(linear);
  }
  int query(int a, int b) {
    a = enter[a], b = enter[b];
    return rmq.query(min(a, b), max(a, b) + 1).second;
  }
  int dist(int a, int b) {
    return depth[a] + depth[b] - 2 * depth[query(a, b)];
  }
};
 
int32_t main(){
    ios_base::sync_with_stdio(false); cin.tie(0);
 
    int n, q; cin >> n >> q;
 
    vector<vector<int>> g(n+5);
    vector<int> c(n);
    vector<array<int, 2>> count(n);
    int leafs=0, root=0;
    for(int i =0; i<n-1; i++){
        int x, y; cin >> x >> y;
        x--; y--;
        g[x].push_back(y);
        g[y].push_back(x);
 
        if(g[x].size()>1) root = x;
        if(g[y].size()>1) root = y;
    }
 
   LCA lca(g, root);
    vector<int> vis(n), tin(n), tout(n);
 
    int cnt = 0;
    auto dfs=[&](int v, int p, auto&& dfs)->void{
        tin[v] = cnt++;
        for(auto i: g[v])
            if(i!=p) dfs(i, v, dfs), c[v]+=c[i];
        
        if(g[v].size()==1) c[v]++, leafs++;
        else vis[v] = 1;
 
        tout[v] = cnt++;
    };
    
    int ans = 0;
 
    auto dfs2=[&](int v, int p, auto&& dfs2)->void{
        //cout<<v+1<<" "<<c[v]<<"\n";
        if(c[v] %2) count[v][1]++;
        else count[v][0]++, ans++;
        for(auto i: g[v]){
            if(i!=p){
                count[i][0]+=count[v][0];
                count[i][1]+=count[v][1];
                dfs2(i, v, dfs2);
            }
        }
    };
 
    dfs(root, root, dfs);
    dfs2(root, root, dfs2) ;
 
    int tmpans = ans, tmpleafs=leafs;
    while(q--){
        int d; cin >> d;
        vector<int> ar(d),a, up;
 
        for(auto &i: ar) cin >> i, i--;
 
        sort(ar.begin(), ar.end(), [&](int x, int y){
            return tin[x] < tin[y];
        }); 
 
        int k=1;
        for(int i=1; i<d; i++){
            if(ar[i]==ar[i-1])k++;
            else{
                 if(g[ar[i-1]].size()==1){
                    leafs+=k-1;
                    if(k%2==0) a.push_back(ar[i-1]);
 
                    k = 1;
                }
                else{
                    leafs+=k;
                    if(k%2==1) a.push_back(ar[i-1]);
                    k=1;
                }
            }
        }
 
        if(g[ar[d-1]].size()==1){
            leafs+=k-1;
            if(k%2==0)  a.push_back(ar[d-1]);
        }
        else{
            leafs+=k;
            if(k%2==1)  a.push_back(ar[d-1]);
        }
 
        up = a; 
        int check =0;
        if(up.size()){
           
            for(int i=0; i<a.size()-1; i++){
                up.push_back(lca.query(a[i], a[i+1]));
            }   
           
     
            sort(up.begin(), up.end(), [&](int x, int y){
                return tin[x] < tin[y];
            });
            
            vector<int> upp;
 
            for(int i=0; i<up.size(); i++){
                if(i==0||up[i]!=up[i-1]) upp.push_back(up[i]);
            }
            up=upp;
            if(up.size()){
                stack<int> st;
 
                st.push(0);
 
                vector<int> p(up.size()), v(up.size());
                vector<vector<int>> adj(up.size());
                vector<int> aa(up.size());
 
                for(int i=1; i<up.size(); i++) {
                    while(st.size() && tout[up[st.top()]] < tin[up[i]]){
                        st.pop();
                    }
                    if(st.size())
                    adj[st.top()].push_back(i), aa[i]++, p[i]=st.top();
                    else p[i]=i;
                    st.push(i);
                }
 
                auto dfsa=[&](int ve, int p, auto&&dfsa)->void{
 
                    for(auto i: adj[ve]){
                        if(i!=p) dfsa(i, ve, dfsa), v[ve]+=v[i];
                    }
                };
                int pos=0;
 
                for(int l=0; l<a.size(); l++){
                    while(pos<up.size()&&up[pos]!=a[l]) pos++;
                    if(pos<up.size()&&up[pos]==a[l]) v[pos]++;
                }
 
                for(int i=0; i<up.size(); i++){
                    if(aa[i]==0) dfsa(i, i, dfsa);
                }
 
 
 
                 for(int i=0; i<up.size(); i++){
                    if(p[i]==i){
                        auto x = count[up[i]];
                        if(v[i]%2){
                            check=1;
                            ans-=x[0]; ans+=x[1];
 
                        }
                    }
                    else if(v[i]%2){
                        auto x=count[up[i]], y=count[up[p[i]]];
                        x[0]-=y[0];
                        x[1]-=y[1];
                        ans-=x[0]; ans+=x[1];
                    }
                }   
            }
        }
 
        if((leafs%2)!=0) cout<<-1<<"\n";
        else cout<<ans-1+d+n-1<<"\n";
 
        ans=tmpans; leafs=tmpleafs;
    }
}

컴파일 시 표준 에러 (stderr) 메시지

cleaning.cpp: In function 'int32_t main()':
cleaning.cpp:168:27: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  168 |             for(int i=0; i<a.size()-1; i++){
      |                          ~^~~~~~~~~~~
cleaning.cpp:179:27: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  179 |             for(int i=0; i<up.size(); i++){
      |                          ~^~~~~~~~~~
cleaning.cpp:192:31: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  192 |                 for(int i=1; i<up.size(); i++) {
      |                              ~^~~~~~~~~~
cleaning.cpp:210:31: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  210 |                 for(int l=0; l<a.size(); l++){
      |                              ~^~~~~~~~~
cleaning.cpp:211:30: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  211 |                     while(pos<up.size()&&up[pos]!=a[l]) pos++;
      |                           ~~~^~~~~~~~~~
cleaning.cpp:212:27: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  212 |                     if(pos<up.size()&&up[pos]==a[l]) v[pos]++;
      |                        ~~~^~~~~~~~~~
cleaning.cpp:215:31: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  215 |                 for(int i=0; i<up.size(); i++){
      |                              ~^~~~~~~~~~
cleaning.cpp:221:32: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  221 |                  for(int i=0; i<up.size(); i++){
      |                               ~^~~~~~~~~~
cleaning.cpp:165:13: warning: variable 'check' set but not used [-Wunused-but-set-variable]
  165 |         int check =0;
      |             ^~~~~
#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...