Submission #575564

#TimeUsernameProblemLanguageResultExecution timeMemory
575564talant117408Joker (BOI20_joker)C++17
100 / 100
316 ms14380 KiB
#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
 
#define pb                  push_back
#define mp                  make_pair
#define all(v)              (v).begin(),(v).end()
#define rall(v)             (v).rbegin(),(v).rend()
#define lb                  lower_bound
#define ub                  upper_bound
#define sz(v)               int((v).size())
#define do_not_disturb      ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl                '\n'

const int N = 2e5+7;
struct query {
    int l, r;
    int index;
    query() {
        l = r = 0;
        index = -1;
    }
};
struct DSU {
    vector <int> link, saizu, color;
    int odd_cycles;
    vector <tuple <int, int, bool>> st;
    
    DSU() {}
    DSU(int n) {
        link.resize(n+1);
        saizu.resize(n+1);
        color.resize(n+1);
        odd_cycles = 0;
        for (int i = 1; i <= n; i++) {
            link[i] = i;
            saizu[i] = 1;
            color[i] = 0;
        }
    }
    int find(int n) {
        if (n == link[n]) return n;
        return find(link[n]);
    }
    int find_color(int n) {
        int x = color[n];
        while (n != link[n]) {
            n = link[n];
            x ^= color[n];
        }
        return x;
    } 
    void unite(int a, int b) {
        int u = a, v = b;
        a = find(a); b = find(b);
        st.emplace_back(a, b, find_color(u) == find_color(v));
        if (a == b) {
            if (find_color(u) == find_color(v)) {
                odd_cycles++;
            }
        }
        else {
            if (saizu[a] < saizu[b]) swap(a, b);
            if (find_color(u) == find_color(v)) color[b] ^= 1;
            color[b] ^= color[a];
            saizu[a] += saizu[b];
            link[b] = a;
        }
    }
    void rollback() {
        auto a = get<0>(st.back()), b = get<1>(st.back());
        auto odd = get<2>(st.back());
        st.pop_back();
        if (a == b) {
            if (odd) {
                odd_cycles--;
            }
        }
        else {
            if (saizu[a] < saizu[b]) swap(a, b);
            saizu[a] -= saizu[b];
            link[b] = b;
        }
    }
    void remove(int x) {
        while (x--) {
            assert(!st.empty());
            rollback();
        }
    }
};
int opt[N], from[N], to[N];
DSU dsu;

void dnc(int l1, int l2, int r1, int r2) {
    if (l1 > l2) return;
    int lmid = (l1+l2) >> 1;
    for (int i = l1; i < lmid; i++) {
        dsu.unite(from[i], to[i]);
    }
    
    opt[lmid] = r2;
    while (!dsu.odd_cycles && opt[lmid] >= r1) {
        dsu.unite(from[opt[lmid]], to[opt[lmid]]);
        opt[lmid]--;
    }
    dsu.remove(r2-opt[lmid]);
    
    dsu.unite(from[lmid], to[lmid]);
    dnc(lmid+1, l2, opt[lmid], r2);
    dsu.remove(lmid-l1+1);
    
    for (int i = opt[lmid]+1; i <= r2; i++) {
        dsu.unite(from[i], to[i]);
    }
    dnc(l1, lmid-1, r1, opt[lmid]);
    dsu.remove(r2-opt[lmid]);
}

void solve() {
    int n, m, q;
    cin >> n >> m >> q;
    dsu = DSU(n);
    for (int i = 1; i <= m; i++) {
        cin >> from[i] >> to[i];
    }
    dnc(1, m, 1, m);
    while (q--) {
        int l, r;
        cin >> l >> r;
        if (r <= opt[l]) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
}

int main() {
    do_not_disturb
    
    int t = 1;
    //~ cin >> t;
    while (t--) {
        solve();
    }
    
    return 0;
}
/*
6 8 8
1 3
1 5
1 6
2 5
2 6
3 4
3 5
5 6
1 3
1 7
1 5
1 1
1 6
1 4
1 2
1 8 

6 8 6
1 3
1 5
1 6
2 5
2 6
3 4
3 5
5 6
1 5
2 5
3 5
4 5
6 7
6 8

6 8 2
1 3
1 5
1 6
2 5
2 6
3 4
3 5
5 6
4 8
4 7

*/
#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...