Submission #1352100

#TimeUsernameProblemLanguageResultExecution timeMemory
1352100tung04885Joker (BOI20_joker)C++20
0 / 100
128 ms13168 KiB
#include <bits/stdc++.h>
using namespace std;
#define MAX 200200
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define fi first
#define se second
#define all(a) (a).begin(),(a).end()
#define __buitin_popcount __builtin_popcountll
#define BIT(x,i) (((x)>>(i))&1ll)
#define MASK(i) (1ll<<(i))

template<class X,class Y> bool maximize(X &x,Y y)
{
    if(x<y)
    {
        x=y;
        return 1;
    }
    return 0;
}

template<class X,class Y> bool minimize(X &x,Y y)
{
    if(y<x)
    {
        x=y;
        return 1;
    }
    return 0;
}

const int inf=1e9+412009;
const ll INF=2e18+412009;

struct DSU
{
    struct NODE
    {
        int u,sz,xr;

        NODE(int _u,int _sz,int _xr)
        {
            u=_u;
            sz=_sz;
            xr=_xr;
        }
    };

    vector<int> par;
    vector<bool> parity;
    vector<int> sz;

    stack<NODE> history;

    int OddCycle=0;

    DSU(int n=0)
    {
        par.resize(n+1);
        parity.assign(n+1,0);
        sz.assign(n+1,1);

        for(int i=1;i<=n;i++) par[i]=i;
    }

    pii find_set(int a)
    {
        bool p=parity[a];

        while(par[a]!=a)
        {
            a=par[a];
            p^=parity[a];
        }

        return {a,p};
    }

    bool union_set(int a,int b)
    {

        pii tmpa=find_set(a);
        pii tmpb=find_set(b);

        a=tmpa.fi;int xa=tmpa.se;
        b=tmpb.fi;int xb=tmpb.se;

        if(b==a)
        {
            history.push(NODE(OddCycle,-1,OddCycle));

            if(xa==xb) OddCycle++;

            return 0;
        }

        if(sz[a]<sz[b]) swap(a,b),swap(xa,xb);

        history.push(NODE(a,sz[a],parity[a]));
        history.push(NODE(b,sz[b],parity[b]));

        par[b]=a;

        parity[b]=xa^xb^1;

        sz[a]+=sz[b];

        return 1;
    }

    void RollBack(int version)
    {
        while(history.size()>version)
        {
            if(history.top().sz==-1)
            {
                OddCycle=history.top().xr;
            }
            else
            {
                int a=history.top().u;

                par[a]=a;

                sz[a]=history.top().sz;

                parity[a]=bool(history.top().xr);
            }

            history.pop();
        }
    }
};

struct EDGE
{
    int u,v;

    int other(int x)
    {
        assert(x==u||x==v);

        return u+v-x;
    }
};

EDGE edge[MAX];
int n,m,q;
vector<int> adj[MAX];

void nhap()
{
    cin>>n>>m>>q;

    for(int i=1;i<=m;i++)
    {
        int u,v;
        cin>>u>>v;

        edge[i]={u,v};

        adj[u].push_back(i);
        adj[v].push_back(i);
    }
}

int f[MAX]={};

void DNC(int l,int r,int optl,int optr,DSU &dsu)
{
    if(l>r) return;

    int mid=l+r>>1;

    int current=dsu.history.size();

    for(int i=l;i<mid;i++) dsu.union_set(edge[i].u,edge[i].v);

    f[mid]=-1;

    for(int i=optr;i>=max(optl,mid+1);i--)
    {
        if(dsu.OddCycle)
        {
            f[mid]=i;
            break;
        }

        dsu.union_set(edge[i].u,edge[i].v);
    }

    if(dsu.OddCycle) maximize(f[mid],mid);

    dsu.RollBack(current);

    int opt=f[mid];

    if(f[mid]==-1) opt=optr;

    DNC(l,mid-1,optl,opt,dsu);

    dsu.RollBack(current);

    for(int i=l;i<=mid;i++) dsu.union_set(edge[i].u,edge[i].v);

    if(f[mid]==-1) opt=optl;

    DNC(mid+1,r,opt,optr,dsu);

    dsu.RollBack(current);
}

void solve()
{
    DSU dsu(n);

    DNC(1,m,1,m,dsu);

    while(q--)
    {
        int l,r;

        cin>>l>>r;

        cout<<(f[l]>=r ? "YES" : "NO")<<'\n';
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);

    nhap();
    solve();

    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...