답안 #702367

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
702367 2023-02-23T16:58:49 Z Cyanmond The Potion of Great Power (CEOI20_potion) C++17
100 / 100
741 ms 148168 KB
#include <bits/stdc++.h>
 
using i64 = long long;
int n, u;
std::vector<int> h;
std::vector<int> a, b;
 
constexpr int inf = 1000000000;
std::array<std::vector<std::pair<int, bool>>, 100000> sMemo;
int memoIdx = 1;
std::vector<std::vector<int>> events, memoList;
constexpr int BS = 5;
 
void init(int N, int d, int H[]) {
    n = N; 
    events.resize(n);
    memoList.resize(n);
    for (int i = 0; i < n; ++i) {
        h.push_back(H[i]);
    }
}
 
bool comp(std::pair<int, bool> a, std::pair<int, bool> b) {
    int x = h[a.first], y = h[b.first];
    if (x == y) {
        return a.first < b.first;
    } else {
        return x < y;
    }
}
 
void curseChanges(int U, int A[], int B[]) {
    u = U;
    for (int i = 0; i < u; ++i) {
        a.push_back(A[i]);
        b.push_back(B[i]);
        events[a[i]].push_back(i);
        events[b[i]].push_back(i);
    }
    for (int x = 0; x < n; ++x) {
        memoList[x].push_back(0);
        std::vector<std::pair<int, bool>> trustList;
        for (int i = 0; i < (int)events[x].size(); ++i) {
            const int j = events[x][i];
            const int v = a[j] xor b[j] xor x;
            auto itr = std::lower_bound(trustList.begin(), trustList.end(), std::make_pair(v, false), comp);
            if (itr == trustList.end() or *itr != std::make_pair(v, true)) {
                trustList.insert(itr, std::make_pair(v, true));
            } else {
                trustList.erase(itr);
            }
            if (i % BS == BS - 1) {
                memoList[x].push_back(memoIdx);
                sMemo[memoIdx++] = trustList;
            }
        }
    }
}
 
int question(int x, int y, int v) {
    // check
    
    auto itr = std::lower_bound(events[x].begin(), events[x].end(), v);
    const int r1 = itr - events[x].begin();
    itr = std::lower_bound(events[y].begin(), events[y].end(), v);
    const int r2 = itr - events[y].begin();
    
    auto &vec1 = sMemo[memoList[x][r1 / BS]];
    auto &vec2 = sMemo[memoList[y][r2 / BS]];
 
    std::vector<int> extraQ1, extraQ2;
    for (int i = r1 / BS * BS; i < r1; ++i) {
        const int j = events[x][i];
        const int v = a[j] xor b[j] xor x;
        extraQ1.push_back(v);
    }
    for (int i = r2 / BS * BS; i < r2; ++i) {
        const int j = events[y][i];
        const int v = a[j] xor b[j] xor y;
        extraQ2.push_back(v);
    }
    const int c = (int)extraQ1.size(), d = (int)extraQ2.size();
    std::unordered_map<int, bool> isOn1(c), isOn2(d);
    for (int i = 0; i < c; ++i) {
        auto itr = std::lower_bound(vec1.begin(), vec1.end(), std::make_pair(extraQ1[i], false), comp);
        if (itr == vec1.end() or itr->first != extraQ1[i]) {
            isOn1[extraQ1[i]] = false;
        } else {
            isOn1[extraQ1[i]] = true;
        }
    }
    for (int i = 0; i < d; ++i) {
        auto itr = std::lower_bound(vec2.begin(), vec2.end(), std::make_pair(extraQ2[i], false), comp);
        if (itr == vec2.end() or itr->first != extraQ2[i]) {
            isOn2[extraQ2[i]] = false;
        } else {
            isOn2[extraQ2[i]] = true;
        }
    }
    
    for (int i = 0; i < c; ++i) {
        isOn1[extraQ1[i]] = not isOn1[extraQ1[i]];
    }
    for (int i = 0; i < d; ++i) {
        isOn2[extraQ2[i]] = not isOn2[extraQ2[i]];
    }
    for (const auto &[v, sta] : isOn1) {
        if (sta) {
            continue;
        }
        auto itr = std::lower_bound(vec1.begin(), vec1.end(), std::make_pair(v, false), comp);
        if (itr == vec1.end() or itr->first != v) {
            continue;
        }
        itr->second = false;
    }
    for (const auto &[v, sta] : isOn2) {
        if (sta) {
            continue;
        }
        auto itr = std::lower_bound(vec2.begin(), vec2.end(), std::make_pair(v, false), comp);
        if (itr == vec2.end() or itr->first != v) {
            continue;
        }
        itr->second = false;
    }
 
    int answer = inf;
    int j = 0;
    for (int i = 0; i < (int)vec1.size(); ++i) {
        if (not vec1[i].second) {
            continue;
        }
        while (j != (int)vec2.size() and (h[vec1[i].first] > h[vec2[j].first] or (not vec2[j].second))) {
            if (j != (int)vec2.size() and vec2[j].second) {
                answer = std::min(answer, std::abs(h[vec2[j].first] - h[vec1[i].first]));
            }
            if ((not vec2.empty()) and j != 0 and vec2[j - 1].second) {
                answer = std::min(answer, std::abs(h[vec1[i].first] - h[vec2[j - 1].first]));
            }
            ++j;
        }
        if (j != (int)vec2.size() and vec2[j].second) {
            answer = std::min(answer, h[vec2[j].first] - h[vec1[i].first]);
        }
        if ((not vec2.empty()) and j != 0 and vec2[j - 1].second) {
            answer = std::min(answer, h[vec1[i].first] - h[vec2[j - 1].first]);
        }
    }
 
    for (const auto &[v, sta] : isOn1) {
        if (not sta) {
            continue;
        }
        auto itr = std::lower_bound(vec2.begin(), vec2.end(), std::make_pair(v, false), comp);
        while (itr != vec2.end() and (not itr->second)) {
            ++itr;
        }
        if (itr != vec2.end()) {
            answer = std::min(answer, std::abs(h[itr->first] - h[v]));
        }
        if (itr == vec2.end()) {
            if (itr == vec2.begin()) {
                continue;
            }
        }
        if (itr != vec2.begin()) {
            --itr;
        }
        while (itr != vec2.begin() and (not itr->second)) {
            --itr;
        }
        if ((not vec2.empty()) and itr->second) {
            answer = std::min(answer, std::abs(h[v] - h[itr->first]));
        }
    }
    for (const auto &[v, sta] : isOn2) {
        if (not sta) {
            continue;
        }
        auto itr = std::lower_bound(vec1.begin(), vec1.end(), std::make_pair(v, false), comp);
        while (itr != vec1.end() and (not itr->second)) {
            ++itr;
        }
        if (itr != vec1.end()) {
            answer = std::min(answer, std::abs(h[itr->first] - h[v]));
        }
        if (itr == vec1.end()) {
            if (itr == vec1.begin()) {
                continue;
            }
        }
        if (itr != vec1.begin()) {
            --itr;
        }
        while (itr != vec1.begin() and (not itr->second)) {
            --itr;
        }
        if ((not vec1.empty()) and itr->second) {
            answer = std::min(answer, std::abs(h[v] - h[itr->first]));
        }
    }
    for (const auto &[v, sta] : isOn1) {
        if (not sta) {
            continue;
        }
        for (const auto &[v2, sta2] : isOn2) {
            if (not sta2) {
                continue;
            }
            answer = std::min(answer, std::abs(h[v] - h[v2]));
        }
    }
 
    for (const auto &[v, sta] : isOn1) {
        if (sta) {
            continue;
        }
        auto itr = std::lower_bound(vec1.begin(), vec1.end(), std::make_pair(v, false), comp);
        if (itr == vec1.end() or itr->first != v) {
            continue;
        }
        itr->second = true;
    }
    for (const auto &[v, sta] : isOn2) {
        if (sta) {
            continue;
        }
        auto itr = std::lower_bound(vec2.begin(), vec2.end(), std::make_pair(v, false), comp);
        if (itr == vec2.end() or itr->first != v) {
            continue;
        }
        itr->second = true;
    }
    return answer;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2640 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 2768 KB Output is correct
2 Correct 4 ms 2768 KB Output is correct
3 Correct 3 ms 2768 KB Output is correct
4 Correct 29 ms 11360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 208 ms 20016 KB Output is correct
2 Correct 232 ms 20016 KB Output is correct
3 Correct 192 ms 23384 KB Output is correct
4 Correct 485 ms 88060 KB Output is correct
5 Correct 273 ms 23468 KB Output is correct
6 Correct 731 ms 130880 KB Output is correct
7 Correct 294 ms 30384 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 224 ms 20040 KB Output is correct
2 Correct 472 ms 143308 KB Output is correct
3 Correct 384 ms 74684 KB Output is correct
4 Correct 457 ms 130180 KB Output is correct
5 Correct 279 ms 26432 KB Output is correct
6 Correct 459 ms 130600 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 49 ms 3972 KB Output is correct
2 Correct 101 ms 4156 KB Output is correct
3 Correct 108 ms 4176 KB Output is correct
4 Correct 219 ms 6088 KB Output is correct
5 Correct 188 ms 5532 KB Output is correct
6 Correct 97 ms 3428 KB Output is correct
7 Correct 216 ms 5692 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2640 KB Output is correct
2 Correct 4 ms 2768 KB Output is correct
3 Correct 4 ms 2768 KB Output is correct
4 Correct 3 ms 2768 KB Output is correct
5 Correct 29 ms 11360 KB Output is correct
6 Correct 208 ms 20016 KB Output is correct
7 Correct 232 ms 20016 KB Output is correct
8 Correct 192 ms 23384 KB Output is correct
9 Correct 485 ms 88060 KB Output is correct
10 Correct 273 ms 23468 KB Output is correct
11 Correct 731 ms 130880 KB Output is correct
12 Correct 294 ms 30384 KB Output is correct
13 Correct 224 ms 20040 KB Output is correct
14 Correct 472 ms 143308 KB Output is correct
15 Correct 384 ms 74684 KB Output is correct
16 Correct 457 ms 130180 KB Output is correct
17 Correct 279 ms 26432 KB Output is correct
18 Correct 459 ms 130600 KB Output is correct
19 Correct 49 ms 3972 KB Output is correct
20 Correct 101 ms 4156 KB Output is correct
21 Correct 108 ms 4176 KB Output is correct
22 Correct 219 ms 6088 KB Output is correct
23 Correct 188 ms 5532 KB Output is correct
24 Correct 97 ms 3428 KB Output is correct
25 Correct 216 ms 5692 KB Output is correct
26 Correct 340 ms 56200 KB Output is correct
27 Correct 466 ms 74872 KB Output is correct
28 Correct 459 ms 65348 KB Output is correct
29 Correct 456 ms 88080 KB Output is correct
30 Correct 741 ms 130436 KB Output is correct
31 Correct 675 ms 148168 KB Output is correct
32 Correct 692 ms 130616 KB Output is correct