답안 #939496

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
939496 2024-03-06T12:04:54 Z Zero_OP 늑대인간 (IOI18_werewolf) C++14
0 / 100
457 ms 101688 KB
#include<bits/stdc++.h>
 
using namespace std;
using int64 = int64_t;
 
#define     REP(i, n) for(int i = 0, _n = n; i < _n; ++i)
#define    REPD(i, n) for(int i = n - 1; i >= 0; --i)
#define  FOR(i, l, r) for(int i = l, _r = r; i <= _r; ++i)
#define FORD(i, r, l) for(int i = r, _l = l; i >= _l; --i)
#define          left __left
#define         right __right
#define          prev __prev
#define          next __next
#define           div __div
#define            pb push_back
#define            pf push_front
#define         sz(v) (int)v.size()
#define      range(v) begin(v), end(v)
#define    compact(v) v.erase(unique(range(v)), end(v))
#define      debug(v) "[" #v " = " << (v) << "]"
 
template<typename T>
    bool minimize(T& a, const T& b){
        if(a > b){
            a = b;
            return true;
        }
        return false;
    }
 
template<typename T>
    bool maximize(T& a, const T& b){
        if(a < b){
            a = b;
            return true;
        }
        return false;
    }
 
template<int dimension, class T>
struct vec : public vector<vec<dimension - 1, T>> {
    static_assert(dimension > 0, "Dimension must be positive !\n");
    template<typename... Args>
    vec(int n = 0, Args... args) : vector<vec<dimension - 1, T>>(n, vec<dimension - 1, T>(args...)) {}
};
 
template<class T>
struct vec<1, T> : public vector<T> {
    vec(int n = 0, T val = T()) : vector<T>(n, val) {}
};
 
struct ReachabilityTree{
    int number_nodes, timer_dfs;
    vector<int> tin, tout, order, lab; 
    vector<vector<int>> adj;
 
    ReachabilityTree(int n, int m){
        number_nodes = n;
        timer_dfs = -1;
        tin = vector<int>(n + m);
        tout = vector<int>(n + m);
        lab = vector<int>(n + m, -1);
        adj = vector<vector<int>>(n + m);
        order = vector<int>();
    }
 
    int find_root(int u){
        return lab[u] < 0 ? u : (lab[u] = find_root(lab[u]));
    }
 
    void unite(int u, int v){
        u = find_root(u);
        v = find_root(v);
        adj[number_nodes].pb(u);
        if(u != v) adj[number_nodes].pb(v);
        lab[u] = number_nodes; lab[v] = number_nodes;
        ++number_nodes;
    }
 
    void dfs(int u){
        tin[u] = ++timer_dfs; order.pb(u);
        for(int v : adj[u]){
            dfs(v);
        }
        tout[u] = timer_dfs;
    }
 
    void process(){
        dfs(number_nodes - 1);
    }
};  
 
struct Fenwick{
    vector<int> bit;
    Fenwick(int n) : bit(n + 1, 0) {}
 
    void update(int id, int val){
        for(; id < sz(bit); id += id & (-id)){
            bit[id] += val;
        }
    }
 
    int query(int id){
        int sum = 0;
        for(; id > 0; id -= id & (-id)){
            sum += bit[id];
        }
        return sum;
    }
 
    int get_range(int l, int r){
        return query(r) - query(l - 1);
    }
};
 
vector<int> check_validity(int N, vector<int> X, vector<int> Y, vector<int> S, vector<int> T, vector<int> L, vector<int> R){
    int n = N;
    int m = sz(X);
    int q = sz(S);
 
    vec<2, int> adj(n);
    REP(i, m){
        int u = X[i], v = Y[i];
        adj[u].pb(v);
        adj[v].pb(u);
    }
 
    ReachabilityTree from(n, m), until(n, m);
    vector<vector<int>> sweep_from(n), sweep_until(n); 
    vector<int> query_from(q), query_until(q);
 
    REP(i, q){
        sweep_from[L[i]].pb(i);
        sweep_until[R[i]].pb(i);
    }
 
    REPD(i, n){
        for(int j : adj[i]){
            if(j >= i){
                from.unite(i, j);
            }
        }
        for(int id : sweep_from[i]){
            query_from[id] = from.find_root(S[id]);
        }
    }
 
    REP(i, n){
        for(int j : adj[i]){
            if(j <= i){
                until.unite(i, j);
            }
        }
        for(int id : sweep_until[i]){
            query_until[id] = until.find_root(T[id]);
        }
    }
 
    from.process();
    until.process();
 
    vector<int> left(q), right(q);
    vector<vector<pair<int, int>>> sweep(n + m);
    REP(i, q){
        int l1 = from.tin[query_from[i]];
        int r1 = from.tout[query_from[i]];
        left[i] = until.tin[query_until[i]];
        right[i] = until.tout[query_until[i]];
        if(l1 > 0) sweep[l1 - 1].pb(make_pair(i, -1));
        sweep[r1].pb(make_pair(i, +1));
    }
 
    auto is_node = [&](int u){
        return -1 < u && u < n;
    };
 
    vector<int> occur(n);
    REP(i, sz(from.order)){
        int u = from.order[i];
        if(is_node(u)){
            occur[u] = i;
        }
    }
 
    vector<int> ans(q);
    Fenwick BIT(n + m);
    REP(i, n + m){
        int u = until.order[i];
        if(is_node(u)){
            BIT.update(occur[u] + 1, 1);
        }
 
        for(const auto& iter : sweep[i]){
            int id = iter.first, sign = iter.second;
            ans[id] += sign * BIT.get_range(left[id] + 1, right[id] + 1); 
        }
    }
 
    REP(i, q){
        minimize(ans[i], 1);
    }
 
    return ans;
}
 
//#define Zero_OP //turn off when submitting
#ifdef Zero_OP
 
void init(void);
void process(void);
 
int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
 
    int T = 1; //cin >> T;
    while(T--) {
        init();
        process();
    }
 
    return 0;
}
 
void init(){
 
}
 
void process(){
    vector<int> ans = check_validity(6, {5, 1, 1, 3, 3, 5}, {1, 2, 3, 4, 0, 2},
{4, 4, 5}, {2, 2, 4}, {1, 2, 3}, {2, 2, 4});
    REP(i, sz(ans)){
        cout << ans[i] << ' ';
    }
    cout << '\n';
}
 
#endif
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 348 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 348 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 457 ms 101688 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 348 KB Output isn't correct
2 Halted 0 ms 0 KB -