제출 #1317469

#제출 시각아이디문제언어결과실행 시간메모리
1317469mikolaj00Joker (BOI20_joker)C++20
25 / 100
195 ms7956 KiB
#include <bits/stdc++.h>
using namespace std;

struct DSU
{
    DSU(int k) : size(k, 1), p(k), color(k)
    {
        for (int i = 0; i < k; i++)
            p[i] = i;
    }

    int find(int k)
    {
        while (k != p[k])
            k = p[k];
        return k;
    }

    bool get_color(int k)
    {
        bool res = false;
        while (k != p[k])
        {
            res ^= color[k];
            k = p[k];
        }
        return res;
    }

    void join(int a, int b)
    {
        int r_a = find(a), r_b = find(b);
        int c_a = get_color(a), c_b = get_color(b);

        if (r_a == r_b)
        {
            st.push({-1, -1, bip});
            if (c_a == c_b)
                bip = false;
            return;
        }

        if (size[r_a] < size[r_b])
        {
            swap(r_a, r_b);
            swap(c_a, c_b);
        }

        st.push({r_b, size[r_a], bip});
        size[r_a] += size[r_b];
        p[r_b] = r_a;
        if (c_a == c_b)
            color[r_b] = true;
        else
            color[r_b] = false;
    }

    void rollback()
    {
        auto[b, s_a, old_bip] = st.top();
        st.pop();

        if (b != -1)
        {
            int a = p[b];
            size[a] = s_a;
            p[b] = b;
        }
        bip = old_bip;
    }

    void add_edge(pair<int, int> e)
    {
        join(e.first, e.second);
    }

    vector<int> size;
    vector<int> p;
    vector<bool> color;
    bool bip = true;
    stack<tuple<int, int, bool>> st;
};

vector<pair<int, int>> edges;
vector<int> last;

void rec(int l1, int r1, int l2, int r2, DSU& dsu)
{
    if (l1 > r1)
        return;

    int mid = (l1+r1)/2;
    int cp1 = dsu.st.size();
    for (int i = l1; i < mid; i++)
        dsu.add_edge(edges[i]);

    int pivot = r2;
    int cp2 = dsu.st.size();
    while (pivot >= l2 && dsu.bip)
    {
        dsu.add_edge(edges[pivot]);
        pivot--;
    }
    last[mid] = pivot;

    while (dsu.st.size() > cp2)
        dsu.rollback();
    dsu.add_edge(edges[pivot]);
    rec(mid+1, r1, pivot, r2, dsu);

    while (dsu.st.size() > cp1)
        dsu.rollback();
    for (int i = pivot+1; i <= r2; i++)
        dsu.add_edge(edges[i]);
    rec(l1, mid-1, l2, pivot, dsu);
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m, q;
    cin >> n >> m >> q;

    DSU dsu(n+1);
    last.resize(m+1);
    edges.resize(m+1);
    for (int i = 1; i <= m; i++)
        cin >> edges[i].first >> edges[i].second;

    rec(1, m, 1, m, dsu);
    for (int i = 0; i < q; i++)
    {
        int l, r;
        cin >> l >> r;

        if (last[l] >= r)
            cout << "YES";
        else
            cout << "NO";
        cout << '\n';
    }
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...