Submission #979406

# Submission time Handle Problem Language Result Execution time Memory
979406 2024-05-10T20:55:01 Z alontanay Keys (IOI21_keys) C++17
20 / 100
505 ms 287820 KB
#include "keys.h"
#include <bits/stdc++.h>
#define f first
#define s second
#define NEW_STATE 0
#define ACTIVE_STATE 1
#define OLD_STATE 2
#define NO_POS -1

using namespace std;
using pi = pair<int,int>;

const int MAX_N = 3e5+5;
namespace dsu {
    int sz[MAX_N], root[MAX_N], L[MAX_N];
    int PTR_pos[MAX_N];
    stack<int> pos[MAX_N];
    int PTR_ord_future[MAX_N];
    set<pi,greater<pi>> ord_future[MAX_N];
    void init(int n) {
        for(int i = 0; i < n; i ++) {
            sz[i] = 1;
            root[i] = i;
            PTR_pos[i] = i;
            PTR_ord_future[i] = i;
        }
    }
    int get_root(int node) {
        if(root[node] == node) {return node;}
        return root[node] = get_root(root[node]);
    }
    void add_pos(int node, int ne) {
        pos[PTR_pos[get_root(node)]].push(ne);
    }
    int poll_pos(int node) {
        int ptr = PTR_pos[get_root(node)];
        if(pos[ptr].empty()) { return NO_POS; }
        int top = pos[ptr].top();
        pos[ptr].pop();
        return top;
    }
    bool are_joined(int a, int b) {
        return get_root(a) == get_root(b);
    }
    int merge(int a, int b) {
        a = get_root(a);
        b = get_root(b);
        if(a == b) { return a; }
        if(sz[a] < sz[b]) {
            swap(a,b);
        }
        L[a] = min(L[a],L[b]);
        root[b] = a;
        {
            int big_ptr = PTR_pos[a];
            int small_ptr = PTR_pos[b];
            if(pos[big_ptr].size() < pos[small_ptr].size()) {
                swap(big_ptr,small_ptr);
            }
            PTR_pos[a] = big_ptr;
            stack<int> &big_pos = pos[big_ptr];
            stack<int> &small_pos = pos[small_ptr];
            while(!small_pos.empty()) {
                big_pos.push(small_pos.top());
                small_pos.pop();
            }
        }
        {
            int big_ptr = PTR_ord_future[a];
            int small_ptr = PTR_ord_future[b];
            if(ord_future[big_ptr].size() < ord_future[small_ptr].size()) {
                swap(big_ptr,small_ptr);
            }
            PTR_ord_future[a] = big_ptr;
            set<pi,greater<pi>> &big_ord_future = ord_future[big_ptr];
            set<pi,greater<pi>> &small_ord_future = ord_future[small_ptr];
            big_ord_future.insert(small_ord_future.begin(),small_ord_future.end());
            small_ord_future.clear();
            while(!big_ord_future.empty() && big_ord_future.begin()->f >= L[a]) {
                pos[big_ptr].push(big_ord_future.begin()->s);
                big_ord_future.erase(big_ord_future.begin());
            }
        }
        return a;
    }
}

vector<pi> nei[MAX_N];
vector<pi> need_key[MAX_N];
int state[MAX_N];
std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c) {
    int n = r.size(), m = u.size();
    dsu::init(n);
    for(int i = 0;i < m; i ++) {
        int a = u[i], b = v[i], t = c[i];
        nei[a].push_back({b,t});
        nei[b].push_back({a,t});
    }
    vector<int> last_occ(n);
    int cidx = 0;
    vector<int> res;
    int opt_score = n;
    for(int i = 0; i < n; i ++) {
        if(state[i] != NEW_STATE) { continue; }
        stack<int> UPD_need_key;
        stack<int> reached_nodes;
        bool reached_old = false;
        int node = i;
        stack<int> comp_stack;
        while(true) {
            cidx++;
            reached_nodes.push(node);
            int key = r[node];
            dsu::L[node] = cidx;
            comp_stack.push(node);
            last_occ[key] = cidx;
            state[node] = ACTIVE_STATE;
            for(auto &[ne, req] : nei[node]) {
                UPD_need_key.push(req);
                need_key[req].push_back({node,ne});
                dsu::ord_future[node].insert({last_occ[req],ne});
            }
            for(pi edge : need_key[key]) {
                dsu::add_pos(edge.f,edge.s);
            }
            need_key[key].clear();

            int next_node;
            bool converged = false;
            while(true) {
                next_node = dsu::poll_pos(node);
                if(next_node == NO_POS) {
                    converged = true;
                    break;
                }
                if(state[next_node] == OLD_STATE) {
                    reached_old = true;
                    break;
                }
                if(state[next_node] == NEW_STATE) {
                    break;
                }
                while(comp_stack.size() >= 2 && !dsu::are_joined(node,next_node)) {
                    int top = comp_stack.top();
                    comp_stack.pop();
                    int bef = comp_stack.top();
                    comp_stack.pop();
                    int new_root = dsu::merge(top,bef);
                    comp_stack.push(new_root);
                }
            }
            if(reached_old || converged) {
                break;
            }
            node = next_node;
        }
        vector<int> base_comp;
        base_comp.reserve(reached_nodes.size());
        while(!reached_nodes.empty()) {
            int top = reached_nodes.top();
            if(!reached_old && dsu::are_joined(node, top)) {
                base_comp.push_back(top);
            }
            reached_nodes.pop();
            state[top] = OLD_STATE;
        }
        if(!reached_old) {
            int score = base_comp.size();
            if(score < opt_score) {
                opt_score = score;
                res.clear();
            }
            if(score == opt_score) {
                res.insert(res.begin(),base_comp.begin(),base_comp.end());
            }
        }
        while(!UPD_need_key.empty()) {
            int key = UPD_need_key.top();
            UPD_need_key.pop();
            need_key[key].clear();
        }
    }
    vector<int> ans(n);
    for(int r : res) {
        ans[r] = 1;
    }
    return ans;
}
# Verdict Execution time Memory Grader output
1 Correct 126 ms 236328 KB Output is correct
2 Correct 100 ms 236112 KB Output is correct
3 Correct 101 ms 236348 KB Output is correct
4 Correct 103 ms 236372 KB Output is correct
5 Correct 98 ms 236116 KB Output is correct
6 Correct 101 ms 236320 KB Output is correct
7 Correct 99 ms 236116 KB Output is correct
8 Correct 97 ms 236368 KB Output is correct
9 Correct 99 ms 236508 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 126 ms 236328 KB Output is correct
2 Correct 100 ms 236112 KB Output is correct
3 Correct 101 ms 236348 KB Output is correct
4 Correct 103 ms 236372 KB Output is correct
5 Correct 98 ms 236116 KB Output is correct
6 Correct 101 ms 236320 KB Output is correct
7 Correct 99 ms 236116 KB Output is correct
8 Correct 97 ms 236368 KB Output is correct
9 Correct 99 ms 236508 KB Output is correct
10 Correct 98 ms 236348 KB Output is correct
11 Correct 103 ms 236628 KB Output is correct
12 Correct 100 ms 236360 KB Output is correct
13 Correct 98 ms 236356 KB Output is correct
14 Correct 104 ms 236276 KB Output is correct
15 Correct 104 ms 236456 KB Output is correct
16 Correct 112 ms 236116 KB Output is correct
17 Correct 102 ms 236180 KB Output is correct
18 Correct 100 ms 236372 KB Output is correct
19 Correct 104 ms 236396 KB Output is correct
20 Correct 98 ms 236116 KB Output is correct
21 Correct 97 ms 236368 KB Output is correct
22 Correct 97 ms 236368 KB Output is correct
23 Correct 101 ms 236224 KB Output is correct
24 Correct 99 ms 236372 KB Output is correct
25 Correct 104 ms 236396 KB Output is correct
26 Correct 97 ms 236444 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 126 ms 236328 KB Output is correct
2 Correct 100 ms 236112 KB Output is correct
3 Correct 101 ms 236348 KB Output is correct
4 Correct 103 ms 236372 KB Output is correct
5 Correct 98 ms 236116 KB Output is correct
6 Correct 101 ms 236320 KB Output is correct
7 Correct 99 ms 236116 KB Output is correct
8 Correct 97 ms 236368 KB Output is correct
9 Correct 99 ms 236508 KB Output is correct
10 Correct 98 ms 236348 KB Output is correct
11 Correct 103 ms 236628 KB Output is correct
12 Correct 100 ms 236360 KB Output is correct
13 Correct 98 ms 236356 KB Output is correct
14 Correct 104 ms 236276 KB Output is correct
15 Correct 104 ms 236456 KB Output is correct
16 Correct 112 ms 236116 KB Output is correct
17 Correct 102 ms 236180 KB Output is correct
18 Correct 100 ms 236372 KB Output is correct
19 Correct 104 ms 236396 KB Output is correct
20 Correct 98 ms 236116 KB Output is correct
21 Correct 97 ms 236368 KB Output is correct
22 Correct 97 ms 236368 KB Output is correct
23 Correct 101 ms 236224 KB Output is correct
24 Correct 99 ms 236372 KB Output is correct
25 Correct 104 ms 236396 KB Output is correct
26 Correct 97 ms 236444 KB Output is correct
27 Correct 100 ms 236628 KB Output is correct
28 Correct 101 ms 236808 KB Output is correct
29 Correct 102 ms 236628 KB Output is correct
30 Correct 99 ms 236560 KB Output is correct
31 Correct 101 ms 236348 KB Output is correct
32 Correct 111 ms 236624 KB Output is correct
33 Correct 101 ms 236364 KB Output is correct
34 Correct 100 ms 236412 KB Output is correct
35 Correct 99 ms 236368 KB Output is correct
36 Correct 111 ms 236796 KB Output is correct
37 Correct 118 ms 236628 KB Output is correct
38 Correct 114 ms 236824 KB Output is correct
39 Correct 110 ms 236628 KB Output is correct
40 Correct 101 ms 236276 KB Output is correct
41 Incorrect 107 ms 236624 KB Output isn't correct
42 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 126 ms 236328 KB Output is correct
2 Correct 100 ms 236112 KB Output is correct
3 Correct 101 ms 236348 KB Output is correct
4 Correct 103 ms 236372 KB Output is correct
5 Correct 98 ms 236116 KB Output is correct
6 Correct 101 ms 236320 KB Output is correct
7 Correct 99 ms 236116 KB Output is correct
8 Correct 97 ms 236368 KB Output is correct
9 Correct 99 ms 236508 KB Output is correct
10 Correct 393 ms 281032 KB Output is correct
11 Correct 505 ms 287820 KB Output is correct
12 Incorrect 163 ms 243900 KB Output isn't correct
13 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 126 ms 236328 KB Output is correct
2 Correct 100 ms 236112 KB Output is correct
3 Correct 101 ms 236348 KB Output is correct
4 Correct 103 ms 236372 KB Output is correct
5 Correct 98 ms 236116 KB Output is correct
6 Correct 101 ms 236320 KB Output is correct
7 Correct 99 ms 236116 KB Output is correct
8 Correct 97 ms 236368 KB Output is correct
9 Correct 99 ms 236508 KB Output is correct
10 Correct 98 ms 236348 KB Output is correct
11 Correct 103 ms 236628 KB Output is correct
12 Correct 100 ms 236360 KB Output is correct
13 Correct 98 ms 236356 KB Output is correct
14 Correct 104 ms 236276 KB Output is correct
15 Correct 104 ms 236456 KB Output is correct
16 Correct 112 ms 236116 KB Output is correct
17 Correct 102 ms 236180 KB Output is correct
18 Correct 100 ms 236372 KB Output is correct
19 Correct 104 ms 236396 KB Output is correct
20 Correct 98 ms 236116 KB Output is correct
21 Correct 97 ms 236368 KB Output is correct
22 Correct 97 ms 236368 KB Output is correct
23 Correct 101 ms 236224 KB Output is correct
24 Correct 99 ms 236372 KB Output is correct
25 Correct 104 ms 236396 KB Output is correct
26 Correct 97 ms 236444 KB Output is correct
27 Correct 100 ms 236628 KB Output is correct
28 Correct 101 ms 236808 KB Output is correct
29 Correct 102 ms 236628 KB Output is correct
30 Correct 99 ms 236560 KB Output is correct
31 Correct 101 ms 236348 KB Output is correct
32 Correct 111 ms 236624 KB Output is correct
33 Correct 101 ms 236364 KB Output is correct
34 Correct 100 ms 236412 KB Output is correct
35 Correct 99 ms 236368 KB Output is correct
36 Correct 111 ms 236796 KB Output is correct
37 Correct 118 ms 236628 KB Output is correct
38 Correct 114 ms 236824 KB Output is correct
39 Correct 110 ms 236628 KB Output is correct
40 Correct 101 ms 236276 KB Output is correct
41 Incorrect 107 ms 236624 KB Output isn't correct
42 Halted 0 ms 0 KB -