답안 #1113251

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1113251 2024-11-16T08:50:08 Z Zero_OP The Potion of Great Power (CEOI20_potion) C++14
100 / 100
871 ms 35476 KB
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 5;
const int MAXQ = 2e5 + 5;
const int C = 50;

int N, D, H[MAXN], pos[MAXN];
vector<int> modified_time[MAXN];
vector<pair<int, int>> modification[MAXN];
vector<vector<int>> blocks[MAXN];

void init(int _N, int _D, int _H[]){
    N = _N;
    D = _D;
    copy(_H, _H + N, H);

    vector<pair<int, int>> v;
    for(int i = 0; i < N; ++i){
        v.emplace_back(H[i], i);
    }

    sort(v.begin(), v.end());
    sort(H, H + N);
    for(int i = 0; i < N; ++i){
        pos[v[i].second] = i;
    }
}

bool on[MAXN], used[MAXN];

void merge_vector(vector<int>& A, const vector<int>& B){
    vector<int> result;
    int i = 0, j = 0;
    while(i < (int)A.size() || j < (int)B.size()){
        if(i == (int)A.size()) result.emplace_back(B[j++]);
        else if(j == (int)B.size()) result.emplace_back(A[i++]);
        else if(A[i] < B[j]) result.emplace_back(A[i++]);
        else result.emplace_back(B[j++]);
    }
    swap(result, A);
}

bool duplicated(const vector<int>& A){
    for(int i = 0; i + 1 < (int)A.size(); ++i) if(A[i] == A[i + 1]) return true;
    return false;
}

bool intersect(const vector<int>& A, const vector<int>& B){
    //just for assertion
    for(auto x : A) if(binary_search(B.begin(), B.end(), x)) return true;
    return false;
}

void addBlock(int u){
    for(int v : blocks[u].back()) on[v] = 1, used[v] = true;
    int sz = (int)modification[u].size();
    vector<int> cur;
    for(int i = sz - C; i < sz; ++i){
        assert(i >= 0);
        int type, v;
        tie(type, v) = modification[u][i];

        if(!used[v]) used[v] = true, cur.push_back(v);

        if(type == -1) on[v] = false;
        if(type == +1) on[v] = true;
    }

    vector<int> old_candidates, new_candidates;
    for(int v : blocks[u].back()) {
        if(on[v]) old_candidates.emplace_back(v);
        on[v] = used[v] = false;
    }
    for(int v : cur) {
        if(on[v]) new_candidates.emplace_back(v);
        on[v] = used[v] = false;
    }

    assert(!duplicated(old_candidates));
    assert(!duplicated(new_candidates));
    assert(!intersect(old_candidates, new_candidates));
    sort(new_candidates.begin(), new_candidates.end());

    blocks[u].emplace_back(old_candidates);
    merge_vector(blocks[u].back(), new_candidates);

//    cout << "addBlock " << u << '\n';
//    for(int i = sz - C; i < sz; ++i) cout << "(" << modification[u][i].first << ' ' << modification[u][i].second << ")\n";
//    for(int v : blocks[u].back()) cout << v << ' '; cout << '\n';
//    cout << '\n';
}

void curseChanges(int U, int A[], int B[]){
    for(int i = 0; i < N; ++i){
        modified_time[i].emplace_back(0);
        blocks[i].emplace_back();
    }

    set<pair<int, int>> pairs;

    for(int i = 0; i < U; ++i){
        int u = A[i], v = B[i];
        u = pos[u]; v = pos[v];
        modified_time[u].emplace_back(i + 1);
        modified_time[v].emplace_back(i + 1);

        if(u > v) swap(u, v);
        if(pairs.count({u, v})){
            modification[u].emplace_back(-1, v);
            modification[v].emplace_back(-1, u);
            pairs.erase({u, v});
        } else{
            modification[u].emplace_back(+1, v);
            modification[v].emplace_back(+1, u);
            pairs.insert({u, v});
        }

        if((int)modification[u].size() % C == 0) addBlock(u);
        if((int)modification[v].size() % C == 0) addBlock(v);
    }
}

vector<int> A, B;

void replay(vector<int>& result, int u, int n_version){
    if(modification[u].empty()) return;
    int B = (n_version) / C;
    int mod = (n_version) % C;

    for(int v : blocks[u][B]){
        on[v] = true;
        used[v] = true;
    }

    vector<int> cur;

    for(int t = 0; t < mod; ++t){
        int i = B * C + t;

        int type, v;
        tie(type, v) = modification[u][i];

        if(!used[v]){
            cur.emplace_back(v);
            used[v] = true;
        }

        if(type == -1) on[v] = false;
        if(type == +1) on[v] = true;
    }

    vector<int> old_candidates, new_candidates;
    for(int v : blocks[u][B]){
        if(on[v]) old_candidates.push_back(v);
        on[v] = used[v] = false;
    }

    for(int v : cur){
        if(on[v]) new_candidates.push_back(v);
        on[v] = used[v] = false;
    }

    sort(new_candidates.begin(), new_candidates.end());
    result = old_candidates;
    merge_vector(result, new_candidates);
}

int question(int x, int y, int v){
    x = pos[x]; y = pos[y];
    int p = upper_bound(modified_time[x].begin(), modified_time[x].end(), v) - modified_time[x].begin() - 1;
    int q = upper_bound(modified_time[y].begin(), modified_time[y].end(), v) - modified_time[y].begin() - 1;
    assert(p >= 0 && q >= 0);
    vector<int>().swap(A);
    vector<int>().swap(B);

    replay(A, x, p);
    replay(B, y, q);

//    cout << x << ' ' << y << '\n';
//    cout << "A : ";
//    for(auto it : A) cout << it << ' '; cout << '\n';
//
//    cout << "B : ";
//    for(auto it : B) cout << it << ' '; cout << '\n';

    if(A.empty() && B.empty()) return (int)1e9;

    int ans = (int)1e9;
    int ptr = 0;
    for(int i = 0; i < (int)A.size(); ++i){
        while(ptr < (int)B.size() && B[ptr] < A[i]) ++ptr;
        if(ptr < (int)B.size()) ans = min(ans, abs(H[A[i]] - H[B[ptr]]));
        if(ptr - 1 >= 0) ans = min(ans, abs(H[A[i]] - H[B[ptr - 1]]));
    }

    return ans;
}

#ifdef LOCAL
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    if(fopen("task.inp", "r")){
        freopen("task.inp", "r", stdin);
        freopen("task.out", "w", stdout);
    }

    int N, D, U, Q;
    cin >> N >> D >> U >> Q;

    int H[N];
    for(int i = 0; i < N; ++i) cin >> H[i];

    int A[U], B[U];
    for(int i = 0; i < U; ++i) cin >> A[i] >> B[i];

    init(N, D, H);
    curseChanges(U, A, B);

    for(int i = 0; i < Q; ++i){
        int x, y, v;
        cin >> x >> y >> v;
        cout << question(x, y, v) << '\n';
    }

    return 0;
}
#endif //LOCAL
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 7504 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 7504 KB Output is correct
2 Correct 7 ms 7516 KB Output is correct
3 Correct 7 ms 7504 KB Output is correct
4 Correct 47 ms 15512 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 362 ms 35048 KB Output is correct
2 Correct 344 ms 35308 KB Output is correct
3 Correct 227 ms 22424 KB Output is correct
4 Correct 553 ms 25904 KB Output is correct
5 Correct 376 ms 26852 KB Output is correct
6 Correct 871 ms 32948 KB Output is correct
7 Correct 420 ms 27336 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 373 ms 35052 KB Output is correct
2 Correct 693 ms 30724 KB Output is correct
3 Correct 569 ms 29620 KB Output is correct
4 Correct 739 ms 33088 KB Output is correct
5 Correct 372 ms 35476 KB Output is correct
6 Correct 813 ms 32996 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 58 ms 9216 KB Output is correct
2 Correct 107 ms 8704 KB Output is correct
3 Correct 136 ms 8704 KB Output is correct
4 Correct 296 ms 8960 KB Output is correct
5 Correct 277 ms 9216 KB Output is correct
6 Correct 103 ms 8540 KB Output is correct
7 Correct 255 ms 8968 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 7504 KB Output is correct
2 Correct 7 ms 7504 KB Output is correct
3 Correct 7 ms 7516 KB Output is correct
4 Correct 7 ms 7504 KB Output is correct
5 Correct 47 ms 15512 KB Output is correct
6 Correct 362 ms 35048 KB Output is correct
7 Correct 344 ms 35308 KB Output is correct
8 Correct 227 ms 22424 KB Output is correct
9 Correct 553 ms 25904 KB Output is correct
10 Correct 376 ms 26852 KB Output is correct
11 Correct 871 ms 32948 KB Output is correct
12 Correct 420 ms 27336 KB Output is correct
13 Correct 373 ms 35052 KB Output is correct
14 Correct 693 ms 30724 KB Output is correct
15 Correct 569 ms 29620 KB Output is correct
16 Correct 739 ms 33088 KB Output is correct
17 Correct 372 ms 35476 KB Output is correct
18 Correct 813 ms 32996 KB Output is correct
19 Correct 58 ms 9216 KB Output is correct
20 Correct 107 ms 8704 KB Output is correct
21 Correct 136 ms 8704 KB Output is correct
22 Correct 296 ms 8960 KB Output is correct
23 Correct 277 ms 9216 KB Output is correct
24 Correct 103 ms 8540 KB Output is correct
25 Correct 255 ms 8968 KB Output is correct
26 Correct 419 ms 26340 KB Output is correct
27 Correct 598 ms 29660 KB Output is correct
28 Correct 658 ms 34612 KB Output is correct
29 Correct 485 ms 25928 KB Output is correct
30 Correct 846 ms 32984 KB Output is correct
31 Correct 740 ms 30584 KB Output is correct
32 Correct 841 ms 32944 KB Output is correct