Submission #1199857

#TimeUsernameProblemLanguageResultExecution timeMemory
1199857dostsJoker (BOI20_joker)C++20
0 / 100
1 ms2624 KiB
#include <bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,popcnt,lzcnt")
//#define int long long
#define vi vector<int>
#define pii pair<int,int> 
#define ff first
#define ss second
#define sp << " " << 
#define all(x) x.begin(),x.end()
 
using namespace std;
const int N = 200001;
pii dad[N];
int sz[N];
int bipartite = 1;
int n,m,q;
pii find(int x) {
    if (x == dad[x].ff) return {x,0};
    pii f = find(dad[x].ff);
    return {f.ff,f.ss^dad[x].ss};
}
vector<pair<int*,int>> upds;
int timer = 0;
void unite(int x,int y) {
    if (!bipartite) return;
    pii a = find(x),b = find(y);
    if (a.ff == b.ff) {
        if (a.ss == b.ss) {
            ++timer;
            upds.push_back({&bipartite,1});
            bipartite = 0;
        }
        return;
    }
    if (sz[a.ff] > sz[b.ff]) swap(a,b);
    timer+=4;
    upds.push_back({&dad[a.ff].ff,dad[a.ff].ff});
    upds.push_back({&dad[a.ff].ss,dad[a.ff].ss});
    upds.push_back({&sz[a.ff],sz[a.ff]});
    upds.push_back({&sz[b.ff],sz[b.ff]});
    sz[b.ff]+=sz[a.ff];
    sz[a.ff] = 0;
    dad[a.ff].ff = b.ff;
    dad[a.ff].ss = a.ss^b.ss^1;
}

void rollback(int t) {
    timer-=t;
    while (t--) {
        *upds.back().ff = upds.back().ss;
        upds.pop_back();
    }
}

struct Query {
    int l,r,id;
};
 
vi a(N),b(N);
int L = 0,R;


void fix(int l,int r) {
    if (l != L) {
        while (L < l) {
            L++;
            unite(a[L],b[L]);
        }
    }
    else {
        while (R > r) {
            R--;
            unite(a[R],b[R]);
        }
    }
}

vi calc(N);
void dnq(int l,int r,int optl,int optr) {
    if (l > r) return;
    if (!bipartite) {
        for (int j = l;j<=r;j++) calc[j] = j;
        return;
    }
    int mid = (l+r) >> 1;
    //l..r hesaplicam optl..optr olabilir [0,l-1] ve optr+1,M edgeleri var 
    int oldtime = timer,oldL = L,oldR = R;
    fix(mid,R); // mid e kadar koydum
    //ilk nereyi koyunca bipartitelığını kaybediyorsa oraya kadar bloklamam lazım
    int ans = m+1;
    for (int i = optr;i>=optl && i > mid;i--) {
        fix(L,i);
        if (!bipartite) {
            ans = i;
            break;
        }
    }
    calc[mid] = ans;
    rollback(timer-oldtime);
    L = oldL,R = oldR;
    oldtime = timer;
    oldL = L,oldR = R;
    fix(L,ans+1);
    //rolback ve fix(L,ans+1)
    dnq(l,mid-1,optl,ans);
    //rolback ve fix(m,R)
    rollback(timer-oldtime);
    L = oldL,R = oldR;
    fix(mid,R);
    dnq(mid+1,r,ans,optr);
}

void solve() {
    cin >> n >> m >> q;
    R = m+1;
    for (int i=1;i<=n;i++) dad[i] = {i,0},sz[i] = 1;
    for (int i=1;i<=m;i++) cin >> a[i] >> b[i];
    dnq(1,m,1,m);
    for (int i=1;i<=q;i++) {
        int l,r;
        cin >> l >> r;
        if (calc[l] <= r) cout << "NO\n";
        else cout << "YES\n";
    }

}
 
signed main() {
    ios_base::sync_with_stdio(0),cin.tie(0);
    #ifdef Dodi
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int t = 1;
    //cin >> t;
    while (t --> 0) solve();
}
#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...