#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 |