Submission #471537

# Submission time Handle Problem Language Result Execution time Memory
471537 2021-09-09T16:54:30 Z blue Parachute rings (IOI12_rings) C++17
0 / 100
1212 ms 98700 KB
#include <iostream>
#include <vector>
using namespace std;

const int maxN = 1'000'000;

struct disjoint_set
{
    int S;
    vector<int> parent;
    vector<int> subtree;

    disjoint_set()
    {
        ;
    }

    disjoint_set(int s)
    {
        S = s;
        parent = vector<int>(S);
        subtree = vector<int>(S);
        for(int i = 0; i < S; i++)
        {
            parent[i] = i;
            subtree[i] = 1;
        }
    }

    int root(int u)
    {
        int v = u;
        while(parent[v] != v) v = parent[v];
        parent[u] = v;
        return v;
    }

    bool connected(int u, int v)
    {
        return root(u) == root(v);
    }

    void join(int u, int v)
    {
        u = root(u);
        v = root(v);
        if(u == v) return;
        if(subtree[u] < subtree[v]) swap(u, v);

        subtree[u] += subtree[v];
        parent[v] = u;
    }
};

const int X = 0;
const int Y = 1;
const int Z = 2;


//general
int state = X;
int N;

//state == X
vector<int> edge[maxN];
disjoint_set prevDSU;

int degree(int u)
{
    return (int)edge[u].size();
}



//state == Y
int cyclic_count = 0;
vector<bool> cyclic(maxN, 0);

void go_to_Y(int label)
{
    state = Y;

    for(int i = 0; i < N; i++)
    {
        if(prevDSU.connected(i, label))
        {
            cyclic[i] = 1;
            cyclic_count++;
        }
    }
}



//state == Z

int Zsize;
vector<int> Z_critical;
vector< vector<int> > Z_degree;
vector<disjoint_set> DSU;
vector<bool> good;

void Z_link(int A, int B)
{
    for(int q = 0; q < Zsize; q++)
    {
        int z = Z_critical[q];
        if(A == z || B == z)
        {
            return;
        }
        if(DSU[q].connected(A, B))
        {
            good[q] = 0;
        }
        Z_degree[q][A]++;
        Z_degree[q][B]++;
        if(Z_degree[q][A] > 2 || Z_degree[q][B] > 2)
            good[q] = 0;

        DSU[q].join(A, B);
    }
}

void go_to_Z(vector<int> V)
{
    cerr << "switching to Z\n";
    state = Z;

    Zsize = V.size();
    Z_critical = V;
    Z_degree = vector< vector<int> >(Zsize, vector<int>(N, 0));
    DSU = vector<disjoint_set>(Zsize, disjoint_set(N));
    good = vector<bool>(Zsize, 1);

    for(int u = 0; u < N; u++)
    {
        for(int v: edge[u])
        {
            if(v < u) continue;
            Z_link(u, v);
        }
    }
}




void Init(int N_)
{
    N = N_;
    prevDSU = disjoint_set(N);
}


int CountCritical()
{
    if(state == X) return N;
    else if(state == Y)
    {
        return cyclic_count;
    }
    else// if(state == Z)
    {
        int res = 0;
        for(int q = 0; q < good.size(); q++)
            res += good[q];

        return res;
    }
}

void Link(int A, int B)
{
    if(state == X)
    {
        if(!prevDSU.connected(A, B))
        {
            if(degree(A) <= 1 && degree(B) <= 1)
            {
                prevDSU.join(A, B);
                edge[A].push_back(B);
                edge[B].push_back(A);
            }
            else if(degree(A) <= 1)
            {
                vector<int> V = edge[B];
                V.push_back(A);
                V.push_back(B);
                go_to_Z(V);
            }
            else if(degree(B) <= 1)
            {
                vector<int> V = edge[A];
                V.push_back(A);
                V.push_back(B);
                go_to_Z(V);
            }
            else
            {
                go_to_Z({A, B});
            }
        }
        else
        {
            if(degree(A) <= 1 && degree(B) <= 1)
            {
                edge[A].push_back(B);
                edge[B].push_back(A);
                go_to_Y(A);
            }
            else if(degree(A) <= 1)
            {
                vector<int> V = edge[B];
                V.push_back(A);
                V.push_back(B);
                go_to_Z(V);
            }
            else if(degree(B) <= 1)
            {
                vector<int> V = edge[A];
                V.push_back(A);
                V.push_back(B);
                go_to_Z(V);
            }
            else
            {
                go_to_Z({});
            }
        }
    }
    else if(state == Y)
    {
        if(cyclic[A] && cyclic[B])
        {
            go_to_Z({A, B});
        }
        else if(cyclic[A] && !cyclic[B])
        {
            edge[A].push_back(A);
            go_to_Z(edge[A]);
        }
        else if(cyclic[B] && !cyclic[A])
        {
            edge[B].push_back(B);
            go_to_Z(edge[B]);
        }
        else
        {
            if(!prevDSU.connected(A, B))
            {
                if(degree(A) <= 1 && degree(B) <= 1)
                {
                    edge[A].push_back(B);
                    edge[B].push_back(A);
                    prevDSU.join(A, B);
                }
                else
                {
                    go_to_Z({});
                }
            }
            else
            {
                go_to_Z({});
            }
        }
    }
    else if(state == Z)
    {
        for(int q = 0; q < (int)Z_critical.size(); q++)
        {
            Z_link(A, B);
        }
    }

    // cerr << CountCritical() << '\n';
}

Compilation message

rings.cpp: In function 'int CountCritical()':
rings.cpp:166:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<bool>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  166 |         for(int q = 0; q < good.size(); q++)
      |                        ~~^~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 13 ms 23884 KB Output is correct
2 Incorrect 16 ms 24328 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 341 ms 51148 KB Output is correct
2 Incorrect 1212 ms 98700 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 13 ms 23884 KB Output is correct
2 Incorrect 16 ms 24328 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 13 ms 23884 KB Output is correct
2 Incorrect 16 ms 24328 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 13 ms 23884 KB Output is correct
2 Incorrect 16 ms 24328 KB Output isn't correct
3 Halted 0 ms 0 KB -