Submission #1339527

#TimeUsernameProblemLanguageResultExecution timeMemory
1339527nguyenkhangninh99Joker (BOI20_joker)C++20
100 / 100
188 ms13628 KiB

#include<bits/stdc++.h>
using namespace std;

#define int long long
const int maxn = 200005;
int edge[maxn][2], minr[maxn], sz[maxn], p[maxn], f[maxn], cc = 0;
stack<pair<int, int>> st;

pair<int, int> find(int u){
    int col = 0;
    while(u != p[u]){
        col ^= f[u];
        u = p[u];
    }
    return {u, col};
}

void merge(int u, int v){
    auto [ru, a] = find(u);
    auto [rv, b] = find(v);

    if(ru == rv){
        cc += (a == b);
        st.push({-1, a == b}); 
        return;
    }

    if(sz[ru] < sz[rv]){
        swap(ru, rv);
        swap(a, b);
    }
    
    f[rv] = (a ^ b ^ 1);
    st.push({ru, rv});
    sz[ru] += sz[rv];
    p[rv] = ru;
}

void rollback(){
    auto [x, y] = st.top();
    st.pop();
    if(x == -1) cc -= y;
    else {
        p[y] = y;
        f[y] = 0;
        sz[x] -= sz[y];
    }
}

void solve(int l, int r, int optl, int optr){
    int mid = (l + r) / 2;
    int cnt0 = 0;
    for(int i = l; i < mid; i++){
        merge(edge[i][0], edge[i][1]);
        cnt0++;
    }

    int ptr = optr, cnt1 = 0;
    while(ptr >= max(mid, optl)){
        merge(edge[ptr][0], edge[ptr][1]);
        cnt1++;
        if(cc) break;
        ptr--;
    }
    while(cnt1--) rollback();

    minr[mid] = ptr;
    merge(edge[mid][0], edge[mid][1]); 
    if(mid + 1 <= r) solve(mid + 1, r, minr[mid], optr);
    rollback();
    while(cnt0--) rollback();

    int cnt2 = 0;
    for(int i = optr; i > minr[mid]; i--){
        merge(edge[i][0], edge[i][1]);
        cnt2++;
    }

    if(l <= mid - 1) solve(l, mid - 1, optl, minr[mid]);
    while(cnt2--) rollback();
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, m, q; cin >> n >> m >> q; 
    for(int i = 1; i <= n; i++) p[i] = i, sz[i] = 1;

    for(int i = 1; i <= m; i++) cin >> edge[i][0] >> edge[i][1];
    for(int i = 1; i <= m; i++){
        merge(edge[i][0], edge[i][1]);
        if(cc){
            while(!st.empty()) rollback();
            for(int i = i + 1; i <= m; i++) minr[i] = m + 1;
            solve(1, i, 1, m);
            break;
        }
    }
    while(q--){
        int l, r; cin >> l >> r;
        cout << (minr[l] <= r ? "NO" : "YES") << '\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...