답안 #1108840

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1108840 2024-11-05T10:35:18 Z AverageAmogusEnjoyer Joker (BOI20_joker) C++17
25 / 100
181 ms 29712 KB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T> bool cmin(T &i, T j) { return i > j ? i=j,true:false; }
template<class T> bool cmax(T &i, T j) { return i < j ? i=j,true:false; }

constexpr int nax = 200200,block_size = 450;
vector<tuple<int,int,int>> queries[block_size]; // r,l,idx
vector<bool> ans;
int edges[nax][2];
int n,m;

struct dsu_save {
    int x,y,lzx,lzy,szx,szy,parx,pary;
    dsu_save(int x,int y,int lzx,int lzy,int szx,int szy,int parx,int pary): x(x), y(y), lzx(lzx), lzy(lzy), szx(szx), szy(szy), parx(parx), pary(pary) {}
};

struct DSU {
    int lz[nax];
    int par[nax];
    int sz[nax];
    stack<dsu_save> stk;
    DSU(int N) {
        for (int i = 0; i < N; i++)
            lz[i] = 0, par[i] = i, sz[i] = 1;
    }
    int get(int x,int &cx) {
        cx ^= lz[x];
        return (x == par[x] ? x : get(par[x],cx));
    }
    bool need_reset = 0;
    bool unite(int x,int y) {
        assert(!need_reset);
        int cx = 0,cy = 0;
        int px = get(x,cx), py = get(y,cy);
        if (sz[px] < sz[py]) 
            swap(px,py), swap(cx,cy);
        stk.emplace(px,py,lz[px],lz[py],sz[px],sz[py],par[px],par[py]);
        if (cx == cy) {
            if (px == py) {
                need_reset = 1;
                return 1;
            } else {
                lz[py] ^= 1;
                sz[px] += sz[py];
                par[py] = px;
            }
        } else {
            if (px != py) {
                sz[px] += sz[py];
                par[py] = px;
            }
        }
        return 0;
    }
    void rollback(int k) {
        need_reset = 0;
        // do stuff
        assert(stk.size() >= k);
        while(k--) {
            auto c = stk.top(); stk.pop();
            lz[c.x] = c.lzx,lz[c.y] = c.lzy,par[c.x] = c.parx,par[c.y] = c.pary,sz[c.x] = c.szx,sz[c.y] = c.szy;
        }
    }
};

DSU dsu(nax); 

bool solve_block(int block) {
    int current_r = m - 1;
    for (int i = max(0,(block - 1) * block_size); i < min(m,block * block_size); i++) {
        if (dsu.unite(edges[i][0],edges[i][1])) {
            for (int B = block; B < block_size; B++) 
                for (auto &[r,l,idx]: queries[B])
                    ans[idx] = 1;
            return 1;
        }
    }
    for (int i = 0; i < queries[block].size(); i++) {
        auto &[r,l,idx] = queries[block][i];
        while(current_r >= r) {
            if (dsu.unite(edges[current_r][0],edges[current_r][1])) {
                for (int j = i; j < queries[block].size(); j++) {
                    int idx2 = get<2>(queries[block][j]);
                    ans[idx2] = 1;
                }
                dsu.rollback(m - current_r); // potrebbero essere necessari dei +- 1
                return 0;
            }
            current_r--;
        }
        --l;
        int inserted = 0;
        while(l >= block * block_size) {
            // devo inserirlo
            inserted++;
            if (dsu.unite(edges[l][0],edges[l][1])) {
                dsu.rollback(inserted);
                ans[idx] = 1;
                break;
            }
            l--;
        }
    }
    return 0;
}

vector<bool> trova_cicli(int N, int M, int Q, vector<int> A, vector<int> B, vector<int> L, vector<int> R) {
    n = N, m = M;
    for (int i = 0; i < M; i++)
        edges[i][0] = A[i],edges[i][1] = B[i];
    ans.resize(Q);
    for (int i = 0; i < Q; i++) 
        queries[L[i] / block_size].emplace_back(R[i],L[i],i);
    for (int i = 0; i < block_size; i++) 
        sort(queries[i].rbegin(),queries[i].rend());
    for (int i = 0; i < block_size; i++) 
        if (solve_block(i))
            break;
    return ans;
}

int main() {

    int N,M,Q;
    cin >> N >> M >> Q;
    vector<int> A(M),B(M),L(Q),R(Q);
    for (int i = 0; i < M; i++) {
        cin >> A[i] >> B[i];
        --A[i],--B[i];
    }
    for (int i = 0; i < Q; i++) {
        cin >> L[i] >> R[i];
        --L[i];
    }
    auto res = trova_cicli(N,M,Q,A,B,L,R);
    for (int i = 0; i < Q; i++) 
        cout << (res[i] ? "YES" : "NO") << "\n";

}

Compilation message

In file included from /usr/include/c++/10/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:33,
                 from Joker.cpp:1:
Joker.cpp: In member function 'void DSU::rollback(int)':
Joker.cpp:59:27: warning: comparison of integer expressions of different signedness: 'std::stack<dsu_save>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   59 |         assert(stk.size() >= k);
      |                ~~~~~~~~~~~^~~~
Joker.cpp: In function 'bool solve_block(int)':
Joker.cpp:79:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::tuple<int, int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   79 |     for (int i = 0; i < queries[block].size(); i++) {
      |                     ~~^~~~~~~~~~~~~~~~~~~~~~~
Joker.cpp:83:35: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::tuple<int, int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   83 |                 for (int j = i; j < queries[block].size(); j++) {
      |                                 ~~^~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2640 KB Output is correct
2 Correct 1 ms 2640 KB Output is correct
3 Correct 1 ms 2640 KB Output is correct
4 Correct 1 ms 2640 KB Output is correct
5 Incorrect 2 ms 2640 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2640 KB Output is correct
2 Correct 1 ms 2640 KB Output is correct
3 Correct 1 ms 2640 KB Output is correct
4 Correct 1 ms 2640 KB Output is correct
5 Incorrect 2 ms 2640 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2640 KB Output is correct
2 Correct 1 ms 2640 KB Output is correct
3 Correct 169 ms 20156 KB Output is correct
4 Correct 173 ms 29712 KB Output is correct
5 Correct 166 ms 23152 KB Output is correct
6 Correct 162 ms 20156 KB Output is correct
7 Correct 162 ms 20120 KB Output is correct
8 Correct 150 ms 19604 KB Output is correct
9 Correct 151 ms 19476 KB Output is correct
10 Correct 172 ms 19868 KB Output is correct
11 Correct 156 ms 20108 KB Output is correct
12 Correct 176 ms 20412 KB Output is correct
13 Correct 159 ms 20116 KB Output is correct
14 Correct 165 ms 20244 KB Output is correct
15 Correct 160 ms 20124 KB Output is correct
16 Correct 181 ms 20500 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2640 KB Output is correct
2 Correct 1 ms 2640 KB Output is correct
3 Correct 1 ms 2640 KB Output is correct
4 Correct 1 ms 2640 KB Output is correct
5 Incorrect 2 ms 2640 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2640 KB Output is correct
2 Correct 1 ms 2640 KB Output is correct
3 Correct 1 ms 2640 KB Output is correct
4 Correct 1 ms 2640 KB Output is correct
5 Incorrect 2 ms 2640 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2640 KB Output is correct
2 Correct 1 ms 2640 KB Output is correct
3 Correct 1 ms 2640 KB Output is correct
4 Correct 1 ms 2640 KB Output is correct
5 Incorrect 2 ms 2640 KB Output isn't correct
6 Halted 0 ms 0 KB -