Advertisement
erek1e

CEOI '20 - The Potion of Great Power

Jul 7th, 2023
696
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.42 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int INF = 1e9;
  6. const int K = 20; // 1 in K updates will be completely recorded
  7.  
  8. int main() {
  9.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  10.     int N, D, U, Q; cin >> N >> D >> U >> Q;
  11.  
  12.     vector<int> H(N);
  13.     for (int &x : H) cin >> x;
  14.  
  15.     vector<vector<vector<int>>> records(N, {{}});
  16.     vector<vector<pair<int, int>>> updates(N, {{0, -1}});
  17.     // first is day. second is update: if negative, index of record, otherwise update
  18.  
  19.     // recordIndex is from 0 in this function
  20.     auto buildState = [&](int a, int recordIndex, int lastUpdate) {
  21.         int prevIndex = recordIndex*K;
  22.         assert(updates[a][prevIndex].second < 0);
  23.         assert(lastUpdate >= prevIndex && lastUpdate-prevIndex <= K); // equal to K when building next record
  24.  
  25.         vector<int> delta;
  26.         for (size_t i = prevIndex+1; i <= lastUpdate; ++i) {
  27.             int v = updates[a][i].second;
  28.             delta.push_back(v);
  29.         }
  30.         sort(delta.begin(), delta.end());
  31.  
  32.         vector<pair<int, bool>> delta2;
  33.         for (int i = 0; i < delta.size(); ++i) {
  34.             if (i+1 < (int)delta.size() && delta[i] == delta[i+1]) ++i;
  35.             else delta2.emplace_back(delta[i], false);
  36.         }
  37.  
  38.         vector<int> result;
  39.         for (int x : records[a][recordIndex]) {
  40.             int id = lower_bound(delta2.begin(), delta2.end(), pair<int, bool>{x, false}) - delta2.begin();
  41.             if (id < (int)delta2.size() && delta2[id].first == x) {
  42.                 assert(!delta2[id].second);
  43.                 delta2[id].second = true;
  44.             } else result.push_back(x);
  45.         }
  46.         for (auto [x, removed] : delta2) {
  47.             if (!removed) result.push_back(x);
  48.         }
  49.         return result;
  50.     };
  51.  
  52.     auto upd = [&](int a, int b, int day) {
  53.         if ((int)updates[a].size() % K == 0) {
  54.             // store entire adjacency list of a once every k updates
  55.             updates[a].emplace_back(day, b);
  56.             vector<int> v = buildState(a, (int)records[a].size()-1, (int)updates[a].size()-1);
  57.             updates[a].pop_back();
  58.             records[a].push_back(v);
  59.  
  60.             updates[a].emplace_back(day, -(int)records[a].size());
  61.         } else {
  62.             // simply store update as toggle
  63.             updates[a].emplace_back(day, b);
  64.         }
  65.     };
  66.  
  67.     for (int day = 1; day <= U; ++day) {
  68.         int a, b; cin >> a >> b;
  69.         upd(a, b, day);
  70.         upd(b, a, day);
  71.     }
  72.  
  73.     auto getFriends = [&](int a, int day) {
  74.         int id = upper_bound(updates[a].begin(), updates[a].end(), pair<int, int>{day, INF}) - updates[a].begin();
  75.         --id;
  76.         int recordID = id / K; // at update recordID * K
  77.         return buildState(a, recordID, id);
  78.     };
  79.  
  80.     while (Q--) {
  81.         int x, y, v; cin >> x >> y >> v;
  82.         vector<int> a = getFriends(x, v), b = getFriends(y, v);
  83.         // sort by H
  84.         for (int &u : a) u = H[u];
  85.         for (int &u : b) u = H[u];
  86.         sort(a.begin(), a.end());
  87.         sort(b.begin(), b.end());
  88.         int minDist = INF;
  89.         for (int i = 0, j = 0; i < (int)a.size(); ++i) { // j is smallest s.t. b[j] >= a[i]
  90.             while (j < (int)b.size() && b[j] < a[i]) ++j;
  91.             if (j) minDist = min(minDist, a[i] - b[j-1]);
  92.             if (j < (int)b.size()) minDist = min(minDist, b[j] - a[i]);
  93.         }
  94.         cout << minDist << endl;
  95.     }
  96.     return 0;
  97. }
  98.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement