답안 #676797

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
676797 2023-01-01T08:07:25 Z dooompy Joker (BOI20_joker) C++17
0 / 100
87 ms 9884 KB
#include "bits/stdc++.h"

using namespace std;

void abc() {cout << endl;}
template <typename T, typename ...U> void abc(T a, U ...b) {
    cout << a << ' ', abc(b...);
}
template <typename T> void printv(T l, T r) {
    while (l != r) cout << *l << " \n"[++l == r];
}
template <typename A, typename B> istream& operator >> (istream& o, pair<A, B> &a) {
    return o >> a.first >> a.second;
}
template <typename A, typename B> ostream& operator << (ostream& o, pair<A, B> a) {
    return o << '(' << a.first << ", " << a.second << ')';
}
template <typename T> ostream& operator << (ostream& o, vector<T> a) {
    bool is = false;
    for (T i : a) {o << (is ? ' ' : '{'), is = true, o << i;}
    return o << '}';
}

#ifdef local
#define test(args...) abc("[" + string(#args) + "]", args)
#else
#define test(args...) void(0)
#endif

using ll = long long;

pair<int, int> roads[200005];


struct dsu {
    vector<pair<int, int>> par;
    vector<int> rnk;
    vector<array<int, 4>> history;

    void init(int n) {
        par.resize(n + 1); rnk.resize(n + 1);
        for (int i = 0; i <= n; i++) {
            par[i] = {i, 0}, rnk[i] = 1;
        }
    }

    pair<int, int> findset(int i) {
        if (i == par[i].first) return par[i];
        int parity = par[i].second;
        pair<int, int> temp =  findset(par[i].first);
        temp.second ^= parity;

        return temp;
    }

    bool onion(int a, int b) {
        auto tempa = findset(a), tempb = findset(b);

        if (tempa.first == tempb.first) {
            if (tempa.second == tempb.second) return false;

            return true;
        }

        if (rnk[a] > rnk[b]) swap(a, b);
        history.push_back({a, rnk[a], b, rnk[b]});

        par[a] = {b, tempa.second^tempb.second^1};

        if (rnk[a] == rnk[b]) rnk[b]++;
        return true;
    }

    void rollback(int idx) {
        while (history.size() > idx) {
            auto [a, rnka, b, rnkb] = history.back();
            history.pop_back();

            rnk[a] = rnka, rnk[b] = rnkb;

            par[a] = {a, 0};
        }
    }
};

dsu ds;
int n, m, q;
int lst[200005];

void dnc(int l, int r, int ql, int qr) {
    if (r < l) return;

    int mid = (l + r) / 2;

    int res = -1;

    int b1 = ds.history.size();
    for (int i = l; i < mid; i++) {
        int id = ds.onion(roads[i].first, roads[i].second);

        if (!id) {
            res = qr;
            break;
        }
    }

    int b2 = ds.history.size();
    if (res == -1) {
        for (int i = qr; i > ql; i--) {
            if (i == m + 1) continue;
            if (ds.onion(roads[i].first, roads[i].second)) {
                res = i; break;
            }
        }

        if (res == -1) res = ql;
    }

    lst[mid] = res;

    if (res == m + 1) {
        for (int i = m + 1; i <= r; i++) lst[i] = m + 1;
    } else {
        ds.rollback(b2);
        if (!ds.onion(roads[mid].first, roads[mid].second)) {
            cout << "REACHED" << endl;
            for (int i = mid + 1; i <= r; i++) lst[i] = m + 1;
        } else {
            dnc(mid + 1, r, lst[mid], qr);
        }
    }

    ds.rollback(b1);
    for (int i = lst[mid] + 1; i <= qr; i++) {
        ds.onion(roads[i].first, roads[i].second);
    }

    dnc(l, mid - 1, ql, lst[mid]);
    ds.rollback(b1);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
//    freopen("", "r", stdin);
//    freopen("", "w", stdout);
    cin >> n >> m >> q;
    for (int i = 1; i <= m; i++) {
        int a, b; cin >> a >> b;
        roads[i] = {a, b};
    }

    ds.init(n);

    dnc(1, m, 1, m + 1);

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

        if (lst[l] <= r) cout << "NO\n";
        else cout << "YES\n";
    }
}

Compilation message

Joker.cpp: In member function 'void dsu::rollback(int)':
Joker.cpp:75:31: warning: comparison of integer expressions of different signedness: 'std::vector<std::array<int, 4> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   75 |         while (history.size() > idx) {
      |                ~~~~~~~~~~~~~~~^~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 336 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Incorrect 1 ms 336 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 336 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Incorrect 1 ms 336 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 336 KB Output is correct
3 Incorrect 87 ms 9884 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 336 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Incorrect 1 ms 336 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 336 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Incorrect 1 ms 336 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 336 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Incorrect 1 ms 336 KB Output isn't correct
5 Halted 0 ms 0 KB -