답안 #256074

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
256074 2020-08-02T09:31:36 Z 문홍윤(#5033) Joker (BOI20_joker) C++17
0 / 100
2000 ms 4428 KB
#include <bits/stdc++.h>
#define pb emplace_back
#define mp make_pair
#define F first
#define S second
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;

struct UNION_FIND{
    int par[400010], sz[400010];
    vector<int> vc;
    UNION_FIND(){for(int i=1; i<=400000; i++)par[i]=i;}
    int findpar(int num){return num==par[num]?num:findpar(par[num]);}
    void mergepar(int a, int b){
        a=findpar(a);
        b=findpar(b);
        if(a==b)return;
        if(sz[a]<sz[b])swap(a, b);
        vc.pb(b);
        par[b]=a;
        sz[a]+=sz[b];
    }
    void rollback(){
        int tmp=vc.back();
        vc.pop_back();
        sz[par[tmp]]-=sz[tmp];
        par[tmp]=tmp;
    }
}uf;

int n, m, q, ans[200010], l, r;
pii edg[200010];

int link(int a, int b){
    uf.mergepar(2*a-1, 2*b);
    uf.mergepar(2*a, 2*b-1);
    if(uf.findpar(2*a)==uf.findpar(2*a-1))return 1;
    return 0;
}

void dnc(int sa, int ea, int sb, int eb){
    if(sa>ea)return;
    assert(sa==l&&eb==r);
    int mid=(sa+ea)/2;
    int tmp1=uf.vc.size();
    int flg=0;
    for(int i=l+1; i<=mid; i++)flg=max(flg, link(edg[i].F, edg[i].S));
    l=mid;
    int tmp2=uf.vc.size();
    if(!flg){
        while(l<r-1){
            r--;
            int sz=uf.vc.size();
            int tmp=link(edg[r].F, edg[r].S);
            if(tmp){
                if(sz<uf.vc.size())uf.rollback();
                if(sz<uf.vc.size())uf.rollback();
                r++;
                break;
            }
        }
    }
    ans[mid]=r;
    while(1){
        if(uf.vc.size()==tmp2)break;
        uf.rollback();
    }
    r=eb;
    link(edg[mid+1].F, edg[mid+1].S);
    l=mid+1;
    dnc(mid+1, ea, ans[mid], eb);
    while(1){
        if(uf.vc.size()==tmp1)break;
        uf.rollback();
    }
    l=sa;
    for(int i=r-1; i>=ans[mid]; i--)link(edg[i].F, edg[i].S);
    r=ans[mid];
    dnc(sa, mid-1, sb, ans[mid]);
    while(1){
        if(uf.vc.size()==tmp1)break;
        uf.rollback();
    }
    r=eb;
}

int main(){
    scanf("%d %d %d", &n, &m, &q);
    int nope=0;
    for(int i=1; i<=m; i++){
        scanf("%d %d", &edg[i].F, &edg[i].S);
        nope=max(nope, link(edg[i].F, edg[i].S));
    }
    r=m+1;
    if(!nope)dnc(0, m, 1, m+1);
    for(int i=1; i<=q; i++){
        int a, b;
        scanf("%d %d", &a, &b);
        if(nope)puts("NO");
        else if(ans[a-1]<=b+1)puts("NO");
        else puts("YES");
    }
}

Compilation message

Joker.cpp: In function 'void dnc(int, int, int, int)':
Joker.cpp:57:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                 if(sz<uf.vc.size())uf.rollback();
                    ~~^~~~~~~~~~~~~
Joker.cpp:58:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                 if(sz<uf.vc.size())uf.rollback();
                    ~~^~~~~~~~~~~~~
Joker.cpp:66:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if(uf.vc.size()==tmp2)break;
            ~~~~~~~~~~~~^~~~~~
Joker.cpp:74:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if(uf.vc.size()==tmp1)break;
            ~~~~~~~~~~~~^~~~~~
Joker.cpp:82:24: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if(uf.vc.size()==tmp1)break;
            ~~~~~~~~~~~~^~~~~~
Joker.cpp: In function 'int main()':
Joker.cpp:89:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d %d %d", &n, &m, &q);
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Joker.cpp:92:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d %d", &edg[i].F, &edg[i].S);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Joker.cpp:99:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d %d", &a, &b);
         ~~~~~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1920 KB Output is correct
2 Correct 2 ms 1920 KB Output is correct
3 Incorrect 2 ms 1920 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1920 KB Output is correct
2 Correct 2 ms 1920 KB Output is correct
3 Incorrect 2 ms 1920 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1920 KB Output is correct
2 Correct 2 ms 1920 KB Output is correct
3 Execution timed out 2065 ms 4428 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1920 KB Output is correct
2 Correct 2 ms 1920 KB Output is correct
3 Incorrect 2 ms 1920 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1920 KB Output is correct
2 Correct 2 ms 1920 KB Output is correct
3 Incorrect 2 ms 1920 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1920 KB Output is correct
2 Correct 2 ms 1920 KB Output is correct
3 Incorrect 2 ms 1920 KB Output isn't correct
4 Halted 0 ms 0 KB -