Submission #856492

# Submission time Handle Problem Language Result Execution time Memory
856492 2023-10-03T17:24:36 Z borisAngelov Colors (RMI18_colors) C++17
61 / 100
514 ms 70080 KB
#include <bits/stdc++.h>

using namespace std;

const int maxn = 150005;

int n, m;

int a[maxn];
int b[maxn];

vector<int> g[maxn];
bool seen[maxn];

vector<int> byAValues[maxn];
vector<int> byBValues[maxn];

struct DSU
{
    struct Roll
    {
        int *pos;
        int val;
        int t;
    };

    int time;
    int par[maxn];
    int dep[maxn];
    stack<Roll> rollback;

    void build(int n)
    {
        time = 1;

        for (int i = 1; i <= n; ++i)
        {
            par[i] = i;
            dep[i] = 1;
        }

        while (!rollback.empty())
        {
            rollback.pop();
        }
    }

    int root(int x)
    {
        if (x == par[x])
        {
            return x;
        }

        rollback.push({&par[x], par[x], time});

        return par[x] = root(par[x]);
    }

    void connect(int x, int y)
    {
        x = root(x);
        y = root(y);

        if (x == y)
        {
            return;
        }

        ++time;

        if (dep[x] > dep[y])
        {
            swap(x, y);
        }

        rollback.push({&par[x], par[x], time});
        par[x] = y;

        if (dep[x] == dep[y])
        {
            rollback.push({&dep[y], dep[y], time});
            ++dep[y];
        }
    }

    void makeRollback(int to)
    {
        time = to;

        while (!rollback.empty() && rollback.top().t > time)
        {
            *rollback.top().pos = rollback.top().val;
            rollback.pop();
        }
    }
};

DSU dsu;

struct edge
{
    int x;
    int y;

    edge()
    {

    }

    edge(int _x, int _y)
    {
        x = _x;
        y = _y;
    }
};

bool isPossible = true;

int seenRoot[maxn];
int timestamp = 0;

struct DynamicConnectivity
{
    vector<edge> tree[4 * maxn];

    void build(int n)
    {
        timestamp = 0;

        for (int i = 1; i <= 4 * n; ++i)
        {
            if (i <= n)
            {
                seenRoot[i] = 0;
            }

            tree[i].clear();
        }
    }

    void addEdge(int node, int l, int r, int from, int to, edge e)
    {
        if (from <= l && r <= to)
        {
            //cout << "put edge on [" << l << ", " << r << "]" << endl;
            tree[node].push_back(e);
            return;
        }

        int mid = (l + r) / 2;

        if (from <= mid)
        {
            addEdge(2 * node, l, mid, from, to, e);
        }

        if (to >= mid + 1)
        {
            addEdge(2 * node + 1, mid + 1, r, from, to, e);
        }
    }

    void divideAndConquer(int node, int l, int r)
    {
        int rollbackTime = dsu.time;

        for (int i = 0; i < tree[node].size(); ++i)
        {
            dsu.connect(tree[node][i].x, tree[node][i].y);
        }

        if (l == r)
        {
            ++timestamp;

            for (int i = 0; i < byAValues[l].size(); ++i)
            {
                //cout << "seen " << byAValues[l][i] << " :: " << dsu.root(byAValues[l][i]) << " on " << timestamp << endl;
                //cout << dsu.root(byAValues[l][i]) << endl;
                seenRoot[dsu.root(byAValues[l][i])] = timestamp;
            }

            for (int i = 0; i < byBValues[l].size(); ++i)
            {
                //cout << "now " << dsu.root(byBValues[l][i]) << ' ' << seen[dsu.root(byBValues[l][i])] << endl;
                if (seenRoot[dsu.root(byBValues[l][i])] != timestamp)
                {
                    //cout << "oh" << endl;
                    isPossible = false;
                }
            }
        }
        else
        {
            int mid = (l + r) / 2;
            divideAndConquer(2 * node, l, mid);
            divideAndConquer(2 * node + 1, mid + 1, r);
        }

        dsu.makeRollback(rollbackTime);
    }

    void addEdge(int from, int to, edge e)
    {
        addEdge(1, 1, n, from, to, e);
    }
};

DynamicConnectivity dynCon;

void reset()
{
    for (int i = 1; i <= n; ++i)
    {
        seen[i] = false;
        g[i].clear();
        byAValues[i].clear();
        byBValues[i].clear();
    }
}

void read()
{
    cin >> n >> m;

    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

    for (int i = 1; i <= n; ++i)
    {
        cin >> b[i];
    }
}

bool hasOutput = false;

void checkTrivialCases()
{
    for (int i = 1; i <= n; ++i)
    {
        if (a[i] < b[i])
        {
            hasOutput = true;
            return;
        }
    }

    for (int i = 1; i <= n; ++i)
    {
        seen[a[i]] = true;
    }

    for (int i = 1; i <= m; ++i)
    {
        if (seen[b[i]] == false)
        {
            hasOutput = true;
            return;
        }
    }
}

void solve()
{
    hasOutput = false;
    checkTrivialCases();

    for (int i = 1; i <= n; ++i)
    {
        byAValues[a[i]].push_back(i);
        byBValues[b[i]].push_back(i);
    }

    dsu.build(n);
    dynCon.build(n);

    for (int i = 1; i <= m; ++i)
    {
        int x, y;
        cin >> x >> y;

        int from = max(b[x], b[y]);
        int to = min(a[x], a[y]);

        if (from <= to && hasOutput == false)
        {
            //cout << "add " << x << " to " << y << " in [" << from << ", " << to << "]" << endl;
            dynCon.addEdge(from, to, edge(x, y));
        }
    }

    if (hasOutput == true)
    {
        cout << "0\n";
        return;
    }

    if (n == 1)
    {
        cout << "1\n";
        return;
    }

    isPossible = true;
    dynCon.divideAndConquer(1, 1, n);

    if (isPossible == true)
    {
        cout << "1\n";
    }
    else
    {
        cout << "0\n";
    }
}

void fastIO()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

int main()
{
    fastIO();

    int q;
    cin >> q;

    while (q--)
    {
        reset();
        read();
        solve();
    }

    return 0;
}

/*
1
4 4
3 3 2 1
2 1 2 1
1 2
2 3
3 4
4 2

add 1 to 2 in [2, 3]
add 2 to 3 in [2, 2]
add 4 to 2 in [1, 1]
*/

Compilation message

colors.cpp: In member function 'void DynamicConnectivity::divideAndConquer(int, int, int)':
colors.cpp:168:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<edge>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  168 |         for (int i = 0; i < tree[node].size(); ++i)
      |                         ~~^~~~~~~~~~~~~~~~~~~
colors.cpp:177:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  177 |             for (int i = 0; i < byAValues[l].size(); ++i)
      |                             ~~^~~~~~~~~~~~~~~~~~~~~
colors.cpp:184:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  184 |             for (int i = 0; i < byBValues[l].size(); ++i)
      |                             ~~^~~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 49 ms 27336 KB Output is correct
2 Correct 22 ms 27904 KB Output is correct
3 Correct 8 ms 27736 KB Output is correct
# Verdict Execution time Memory Grader output
1 Incorrect 32 ms 27224 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 57 ms 27224 KB Output is correct
2 Correct 26 ms 27832 KB Output is correct
3 Correct 8 ms 27600 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 57 ms 27224 KB Output is correct
2 Correct 26 ms 27832 KB Output is correct
3 Correct 8 ms 27600 KB Output is correct
4 Correct 117 ms 30292 KB Output is correct
5 Correct 313 ms 49404 KB Output is correct
6 Correct 514 ms 70080 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 49 ms 27336 KB Output is correct
2 Correct 22 ms 27904 KB Output is correct
3 Correct 8 ms 27736 KB Output is correct
4 Correct 57 ms 27224 KB Output is correct
5 Correct 26 ms 27832 KB Output is correct
6 Correct 8 ms 27600 KB Output is correct
7 Correct 58 ms 28592 KB Output is correct
8 Correct 25 ms 27848 KB Output is correct
9 Correct 9 ms 27736 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 105 ms 27612 KB Output is correct
2 Correct 295 ms 51216 KB Output is correct
3 Correct 280 ms 58684 KB Output is correct
# Verdict Execution time Memory Grader output
1 Incorrect 20 ms 27228 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 49 ms 27336 KB Output is correct
2 Correct 22 ms 27904 KB Output is correct
3 Correct 8 ms 27736 KB Output is correct
4 Incorrect 32 ms 27224 KB Output isn't correct
5 Halted 0 ms 0 KB -