제출 #1299251

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


#define pb push_back
#define eb emplace_back
#define F first
#define S second

typedef pair<int,int> ii;
typedef tuple<int,int,int> iii;  

template<typename T>
using vec = vector<T>; 
using i64 = long long; 

struct DSU{
    int n; 
    vec<int> dsu,dist; 
    stack<iii> history; 
    DSU(int n) : n(n){
        dsu.assign(n,-1);
        dist.assign(n,0);  
    }

    ii find(int x){
        int d = 0; 
        while (dsu[x] >= 0){
            d ^= dist[x];
            x = dsu[x]; 
        } 
        return {x,d};  
    }

    bool merge(int x,int y){
        int distx,disty,px,py; 
        tie(px,distx) = find(x); 
        tie(py,disty) = find(y); 

        if (px == py) {
            if (distx == disty){
                return false; 
            }  
            return true; 
        } 
        if (dsu[px] > dsu[py]) swap(px,py); 
        history.push({px,py,dsu[py]}); 

        dsu[px] += dsu[py]; 
        dsu[py] = px; 
        dist[py] = (distx + 1 + disty) & 1; 
        return true; 
    }

    int snapshot(){
        return history.size(); 
    }

    void rollback(int until){
        while (snapshot() > until){
            int root,child,childsiz; tie(root,child,childsiz) = history.top();
            history.pop(); 
            dsu[child] = childsiz;
            dsu[root] -= childsiz;
            dist[child] = 0;  
        }
    }
}; 

int n,m,q; 
vec<ii> edges; 
vec<ii> queries; 
vec<bool> ans; 
DSU dsu(2e5 + 100); 
vec<int> last; 


void dac(int l,int r,int y){
    if (l == r) return; 
    int m = (l + r)  / 2; 
    int siz1 = dsu.snapshot();
    for (int i = l; i < m; i++) dsu.merge(edges[i].F,edges[i].S);

    int siz2 = dsu.snapshot(); 
    int tmpy = y; 
    while (tmpy > m && dsu.merge(edges[tmpy-1].F,edges[tmpy-1].S)) tmpy--; 
    last[m] = tmpy; 
    dsu.rollback(siz2); 
    dsu.merge(edges[m].F,edges[m].S);
    dac(m+1,r,y); 
    dsu.rollback(siz1); 
    for (int i = tmpy; i < y; i++){
        dsu.merge(edges[i].F,edges[i].S); 
    }
    dac(l,m,tmpy); 
    dsu.rollback(siz1); 
}


int main(){
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); 
    cin >> n >> m >> q;
    ans.assign(q + 1,false); 
    last.assign(m + 1,-1); 

    for (int i = 0; i < m; i++){
        int a,b; cin >> a >> b; 
        a--; b--; 
        edges.eb(a,b); 
    }

    for (int i = 0; i < q; i++){
        int l,r; cin >> l >> r; 
        l--; r--; 
        queries.eb(l,r); 
    }
    int x = 0;
    while (x < m && dsu.merge(edges[x].F,edges[x].S)) x++;

    for (int i = x + 1; i < m; i++) last[i] = m+1; 


    dsu.rollback(0); 
    dac(0,min(m,x+1),m); 

    for (int i = 0; i < q; i++){
        int l,r; tie(l,r) = queries[i]; 
        
        if (last[l] <= r+1) cout << "NO" << endl; 
        else cout << "YES" << endl; 
    }

    return 0; 
}
#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...