답안 #539081

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
539081 2022-03-18T11:24:04 Z Jeff12345121 동기화 (JOI13_synchronization) C++14
20 / 100
684 ms 39248 KB
#include <bits/stdc++.h>
#define dbg(x) if(COND) {cout << #x << "=" << x << "\n";}
#define dbgp(x) if(COND) {cout << #x << "= {" << x.first << "," << x.second << "}\n";}
#define dbgv(x) if(COND) {cout << #x << ": "; for (auto k : x) { cout << k << " "; } cout << "\n";}
#define dbgvp(x) if(COND) {cout << #x << ":\n"; for (auto k : x) { dbgp(k) } cout << "\n";}
#define dbgm(x) if(COND) {int ind = 0; cout << #x << ":\n"; for (auto k : x) { cout << ind++ << ": "; for (auto p : k) {cout << p << " ";} cout << "\n";} cout << "\n";}
#define dbgmp(x) if(COND) {int ind = 0; cout << #x << ":\n"; for (auto k : x) { cout << ind++ << ": "; for (auto p : k) {cout << "{" << p.first << "," << p.second << "} ";} cout << "\n";} cout << "\n";}
#define dbga(x , n) if(COND) {cout << #x << ": "; for(int i = 1; i <= n; i++) { cout << a[i] << " "; } cout << "\n";}
#define dbga2(x , n , m) if(COND) {cout << #x << ":\n"; for(int i = 1; i <= n; i++) { cout << i << ": "; for (int j = 1; j <= m; j++) {cout << a[i][j] << " ";} cout << "\n"; } cout << "\n";}
#define brk(x) if(x) { COND = true; } else { COND = false; }
#define sep if (COND) {cout << "\n-------------------------------\n\n";}
#define dbgdeq(q) if (COND) {cout << #q << ": "; deque<int> qc = q; while(!qc.empty()) {cout << qc.front() << " "; qc.pop_front();} cout << "\n"; }
#define int long long
using namespace std;

bool COND = true;


#ifdef LOCAL
ifstream in("in.in");
ofstream out("out.out");
#else
#define in cin
#define out cout
#endif // LOCAL

int n,m,q;
const int nmax = 300005;
vector<vector<pair<int,int>>> g;
vector<pair<int,int>> lines;

int nrEuler;

///returns the number of inactive edges from node to root

struct Bit {
    int v[nmax];
    int query(int pos) {
        int s = 0;
        for (; pos > 1; pos -= (pos &(-pos))) {
            s += v[pos];
        }
        return s;
    }
    void update(int pos, int val) {
        for (; pos <= nrEuler; pos += (pos & (-pos))) {
            v[pos] += val;
        }
    }
};
Bit bit;

vector<int> par,first,last,Rank;
///returns the number of inactive nodes from root to node
int inactive(int node) {
    return bit.query(first[node]);
}

void euler(int node, int &ind) {
    first[node] = ++ind;
    for (auto k : g[node]) {
        if (par[node] == k.first) continue;
        par[k.first] = node;
        Rank[k.first] = Rank[node] + 1;
        euler(k.first , ind);
    }
    last[node] = ++ind;
}

///returns the highest node in the component of 'node', which is the first
///node that has less inactive components than node.
const int MAXPUT = 20;
int lift[MAXPUT][nmax];
void getLift() {
    for (int i = 1; i <= n; i++) {
        lift[0][i] = par[i];
    }
    for (int p = 1; (1 << p) <= n; p++) {
        for (int i = 1; i <= n; i++) {
            lift[p][i] = lift[p - 1][lift[p - 1][i]];
        }
    }
    /*
    for (int p = 0; p <= 10; p++) {
        for (int i = 1; i <= n; i++) {
            cout << "p = " << p << " i = " << i << ": " << lift[p][i] << "\n";
        }
        cout << "\n";
    }cout << "\n";*/
}
int root(int node) {
    int nodeInactive = inactive(node);
    int r = node;
    for (int p = MAXPUT - 1; p >= 0; p--) {
        if (lift[p][r] == 0) continue;
        if (inactive(lift[p][r]) == nodeInactive) {
            r = lift[p][r];
        }
    }
    return r;
}
int32_t main() {
    in >> n >> m >> q;
    lines.resize(n);
    g.resize(n + 1);
    par.resize(n + 1);
    first.resize(n + 1);
    last.resize(n + 1);
    Rank.resize(n + 1);
    for (int i = 1; i < n; i++) {
        int u,v;
        in >> u >> v;
        g[u].push_back({v,i});
        g[v].push_back({u,i});
        lines[i] = {u,v};
    }



    nrEuler = 0;
    euler(1 , nrEuler);


    auto deactivate = [&](int u, int v) {
        ///u is parent, v is child
        if (Rank[u] > Rank[v]) swap(u,v);

        bit.update(first[v] , 1);
        bit.update(last[v]  , -1);
    };

    auto activate = [&](int u, int v) {
        if (Rank[u] > Rank[v]) swap(u,v);

        bit.update(first[v] , -1);
        bit.update(last[v]  , 1);
    };

    for (int i = 1; i < n; i++) {
        deactivate(lines[i].first , lines[i].second);
    }

    getLift();

    vector<int> sol(n + 1 , 1);
    vector<int> status(n , 0); /// 0 = inactive, 1 = active

    vector<int> qs(m + 1);
    vector<int> appearence(n + 1, 0);
    for (int i = 1; i <= m; i++) {
        in >> qs[i];
        appearence[qs[i]]++;
    }
    vector<int> qs2;
    vector<int> needed(n , 0);
    qs2.push_back(0);
    for (int i = 1; i < n; i++) {
            if (appearence[i] > 0 && appearence[i] % 2 == 0) needed[i] = 2;
    else if (appearence[i] > 0)
            needed[i] = 1;
    }
   // dbgv(appearence);
 //   dbgv(needed);
    for (int i = 1; i <= m; i++) {
        if (appearence[qs[i]] > needed[qs[i]]) {
            appearence[qs[i]]--;
        } else {
            qs2.push_back(qs[i]);
        }
    }

    //dbgv(qs2);

    for (int i = 1; i < qs2.size(); i++) {
        int ind = qs2[i];
        int u = lines[ind].first;
        int v = lines[ind].second;



        ///u is parent, v is child
        if (Rank[u] > Rank[v]) swap(u,v);
        if (status[ind] == 0) { /// its currently inactive
            int r = root(u);
            sol[r] += sol[v];
          //  lastAdded[ind] = sol[v];
            activate(u , v);
            status[ind] = 1;
        } else {
            sol[v] = sol[root(u)];
            deactivate(u,v);
            status[ind] = 0;
        }
    }

    for (int i = 1; i <= q; i++) {
        int x;
        in >> x;
        out << sol[root(x)] << "\n";
    }
}






Compilation message

synchronization.cpp: In function 'int32_t main()':
synchronization.cpp:174:23: 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]
  174 |     for (int i = 1; i < qs2.size(); i++) {
      |                     ~~^~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Incorrect 0 ms 340 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 133 ms 36016 KB Output is correct
2 Correct 139 ms 35488 KB Output is correct
3 Correct 164 ms 38316 KB Output is correct
4 Correct 156 ms 38304 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 684 ms 39248 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Incorrect 1 ms 340 KB Output isn't correct
3 Halted 0 ms 0 KB -