제출 #814030

#제출 시각아이디문제언어결과실행 시간메모리
814030PixelCatKeys (IOI21_keys)C++17
9 / 100
1266 ms400624 KiB
#ifdef NYAOWO
#include "grader.cpp"
#endif

#include <bits/stdc++.h>
#define For(i, a, b) for(int i = a; i <= b; i++)
#define Forr(i, a, b) for(int i = a; i >= b; i--)
#define F first
#define S second
#define sz(x) ((int)x.size())
#define all(x) x.begin(), x.end()
#define eb emplace_back
// #define int LL
using namespace std;
using i32 = int32_t;
using LL = long long;
using pii = pair<int, int>;

const int MAXN = 300'000;
const int MAXK = 300'000;  // max types of keys
const int MAXND = 1'000'000;

struct PairHash {
    int operator()(const pii &p1) const {
        return p1.F * MAXK + p1.S;
    }
};

struct SCC {
    int node_count = 0;
    unordered_map<pii, int, PairHash> mp;  // pair{room, key}
    pii rk[MAXND + 10];

    vector<int> adj[MAXND + 10];
    vector<int> rev[MAXND + 10];
    int vis[MAXND + 10];
    vector<int> stk;
    vector<int> scc[MAXND + 10];
    bool broken[MAXND + 10];
    
    int rk2id(int r, int k) {
        pii p(r, k);
        if(!mp.count(p)) {
            mp[p] = node_count;
            rk[node_count] = p;
            node_count++;
        }
        return mp[p];
    }
    pii id2rk(int id) {
        return rk[id];
    }

    void link(int r1, int k1, int r2, int k2) {
        int x = rk2id(r1, k1);
        int y = rk2id(r2, k2);
        adj[x].eb(y);
        rev[y].eb(x);
    }
    void bilink(int r1, int k1, int r2, int k2) {
        link(r1, k1, r2, k2);
        link(r2, k2, r1, k1);
    }

    void dfs1(int n) {
        if(vis[n] < 0) return;
        vis[n] = -1;
        for(auto &i:rev[n]) dfs1(i);
        stk.eb(n);
    }
    void dfs2(int n, int tag) {
        if(vis[n] != -1 && vis[n] != tag) broken[tag] = 1;
        if(vis[n] != -1) return;
        vis[n] = tag;
        scc[tag].eb(n);
        for(auto &i:adj[n]) dfs2(i, tag);
    }
    int build_scc() {
        memset(vis, 0, sizeof(vis));
        For(i, 0, node_count - 1) dfs1(i);
        int cur_scc = 0;
        while(sz(stk)) {
            dfs2(stk.back(), cur_scc);
            while(sz(stk) && vis[stk.back()] != -1) stk.pop_back();
            cur_scc++;
        }
        return cur_scc;
    }
} ayaya;

vector<i32> find_reachable(vector<i32> R, vector<i32> U, vector<i32> V, vector<i32> C) {
    int n = sz(R);
    int m = sz(C);

    For(i, 0, m - 1) ayaya.bilink(U[i], C[i], V[i], C[i]);
    For(k, 0, 29) For(r, 0, n - 1) {
        ayaya.link(r, k, r, R[r]);
    }
    int nscc = ayaya.build_scc();

    vector<int> reach(n, -1);
    vector<int> in_use(n, 0);
    int mn = n + 48763;
    For(sccid, 0, nscc - 1) if(!ayaya.broken[sccid]) {
        int cnt = 0;
        vector<int> start;
        for(auto &id:ayaya.scc[sccid]) {
            int r, k;
            tie(r, k) = ayaya.id2rk(id);
            if(k == R[r]) start.eb(r);
            cnt += (in_use[r] == 0);
            in_use[r] = 1;
        }
        for(auto &i:start) {
            reach[i] = cnt;
            mn = min(mn, cnt);
        }
        for(auto &id:ayaya.scc[sccid]) {
            in_use[ayaya.id2rk(id).F] = 0;
        }
    }

    vector<i32> ans(n);
    For(i, 0, n - 1) {
        ans[i] = (reach[i] == mn);
    }
    return ans;
}

/*

4 5
0 1 1 2
0 1 0
0 2 0
1 2 1
1 3 0
3 1 2

0 1 1 0


7 10
0 1 1 2 2 1 2
0 1 0
0 2 0
1 2 1
1 3 0
2 3 0
3 4 1
3 5 2
4 5 0
4 6 2
5 6 1

0 1 1 0 1 0 1


3 1
0 0 0
0 1 0

0 0 1

*/
#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...