제출 #1353481

#제출 시각아이디문제언어결과실행 시간메모리
1353481matus192The Potion of Great Power (CEOI20_potion)C++20
38 / 100
3027 ms99212 KiB
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> oset;

#define ff first
#define ss second
#define pb push_back
#define all(x) x.begin(), x.end()
#define IMAX INT_MAX
#define IMIN INT_MIN
#define LMAX LLONG_MAX
#define LMIN LLONG_MIN
#define MOD 1000000007
#define SIR 1000000009

int n, d;
vll vals;

struct cmpVals {
    bool operator()(const int x, const int y) const {
        if (vals[x] != vals[y]) return vals[x] < vals[y];
        return x < y;
    }
};

struct sused {
    int id, zac, kon = IMAX;
    sused* nxt = nullptr;
    vector<pair<int, sused*>> prv = {{0, nullptr}};
    sused() {};
};

const int MAX_NODES = 500005;
sused mem_pool[MAX_NODES];
int pool_sz = 0;

sused* create_sused(int id, int cas) {
    sused* nw = &mem_pool[pool_sz++];
    nw->id = id;
    nw->zac = cas;
    nw->kon = IMAX;
    nw->nxt = nullptr;
    nw->prv.reserve(2); 
    nw->prv.push_back({0, nullptr});
    return nw;
}

struct saman {
    map<int, int> sus;
    vector<sused*> adj;
    sused* last;

    saman() {
        auto rnd = create_sused(-1, -1);
        adj = {rnd};
        sus = map<int, int>();
        last = adj[0];
    }

    bool susedi(int id) {
        return (sus.find(id) != sus.end());
    }

    void pridaj(int id, int cas) {
        sused* nw = create_sused(id, cas);
        nw->prv.emplace_back(cas, last);
        sus[id] = adj.size();
        adj.pb(nw);
        if (last) last->nxt = nw;
        last = nw;
    }

    void odober(int id, int cas) {
        int idx = sus[id];
        auto torem = adj[idx];
        torem->kon = cas;
        if (last == torem) last = torem->prv.back().ss;

        auto prvs = torem->prv.back().ss;
        auto nxts = torem->nxt;

        if (prvs) prvs->nxt = nxts;
        if (nxts) nxts->prv.emplace_back(cas, prvs);
        sus.erase(id);
    }

    vi najdi_susedov(int cas) {
        vi res;

        int b = 0, e = adj.size();
        while (e - b > 1) {
            auto ono = adj[(b + e) / 2];
            if (ono->zac <= cas)
                b = (b + e) / 2;
            else
                e = (b + e) / 2;
        }

        auto cur = adj[b];

        while (cur->id >= 0) {
            if (cur->kon > cas) res.pb(cur->id);
            b = 0; e = cur->prv.size();
            while (e - b > 1) {
                int tmp = cur->prv[(b+e)/2].ff;
                if (tmp > cas) e = (b+e)/2;
                else b = (b+e)/2;
            } 

            cur = cur->prv[b].ss;
        }
        sort(all(res), cmpVals());
        return res;
    }
};

vector<saman*> vrch;
void init(int N, int D, int H[]) {
    n = N;
    d = D;
    vals.resize(n);
    for (int i = 0; i < n; i++) vals[i] = H[i];
    vrch = vector<saman*>(n);
    for (int i = 0; i < n; i++) {
        vrch[i] = new saman();
    }
}

void curseChanges(int U, int A[], int B[]) {
    for (int i = 1; i <= U; i++) {
        int a = A[i - 1], b = B[i - 1];
        if (!vrch[a]->susedi(b)) {
            vrch[a]->pridaj(b, i);
            vrch[b]->pridaj(a, i);
        } else {
            vrch[a]->odober(b, i);
            vrch[b]->odober(a, i);
        }
    }
}

int question(int x, int y, int v) {
    auto adjx = vrch[x]->najdi_susedov(v);
    auto adjy = vrch[y]->najdi_susedov(v);
    if (adjx.size() == 0 || adjy.size() == 0) {
        return 1000000000;
    }

    ll best = LMAX;
    int ix = 0, iy = 0;
    while  (ix < adjx.size() && iy < adjy.size()) {
        best = min(best, llabs(vals[adjx[ix]] - vals[adjy[iy]]));
        if (vals[adjx[ix]] < vals[adjy[iy]]) ix++;
        else iy++;
    }

    return best;
}

// int main() {
//   int N, D, U, Q;
//   std::ios::sync_with_stdio(false); std::cin.tie(NULL);
//   std::cin >> N >> D >> U >> Q;

//   int *F = new int[N];
//   for (int i=0; i<N; i++)
//     std::cin >> F[i];
//   init(N, D, F);

//   int *A = new int[U], *B = new int[U];
//   for (int i=0; i<U; i++) {
//     std::cin >> A[i] >> B[i];
//   }
//   curseChanges(U, A, B);

//   bool correct = true;
//   for (int i=0; i<Q; i++) {
//     int X,Y,V,CorrectAnswer;
//     std::cin >> X >> Y >> V >> CorrectAnswer;
//     int YourAnswer = question(X,Y,V);
//     if (YourAnswer != CorrectAnswer) {
//       std::cout << "WA! Question: " << i
// 		<< " (X=" << X << ", Y=" << Y << ", V=" << V << ") "
// 		<<  "Your answer: " << YourAnswer
//                 << " Correct Answer: " << CorrectAnswer << std::endl;
//       correct = false;
//     } else {
//       std::cerr << YourAnswer << " - OK" << std::endl;
//     }
//   }

//   if (correct) {
//     std::cout << "Correct." << std::endl;
//   } else std::cout << "Incorrect." << std::endl;
//   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...