이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int inf = 1e9 + 5;
vector<vector<int>> sp1, sp2;
vector<int> lg;
int get1(int l, int r){
int k = lg[r - l + 1];
return max(sp1[l][k], sp1[r - (1 << k) + 1][k]);
}
int get2(int l, int r){
int k = lg[r - l + 1];
return min(sp2[l][k], sp2[r - (1 << k) + 1][k]);
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n; cin>>n;
vector<int> x(n + 2);
for (int i = 1; i <= n; i++){
cin>>x[i];
}
x[0] = x[1];
x[n + 1] = x[n];
int q; cin>>q;
vector<int> :: iterator it;
auto left = [&](int k) -> int{
if (k == x[n]) return n;
it = upper_bound(x.begin() + 1, x.end(), k);
return (int) (prev(it) - x.begin());
};
auto right = [&](int k) -> int{
it = lower_bound(x.begin() + 1, x.end(), k);
return (int) (it - x.begin());
};
lg.resize(n + 1);
for (int i = 2; i <= n; i++){
lg[i] = lg[i / 2] + 1;
}
sp1.resize(n + 1);
sp2.resize(n + 1);
for (int i = 1; i <= n; i++){
sp1[i].resize(lg[n] + 1);
sp2[i].resize(lg[n] + 1);
}
for (int i = 1; i <= n; i++){
sp1[i][0] = 2 * x[i] - x[i - 1];
sp2[i][0] = 2 * x[i] - x[i + 1];
}
for (int j = 1; j <= lg[n]; j++){
for (int i = 1; i + (1 << j) <= n + 1; i++){
sp1[i][j] = max(sp1[i][j - 1], sp1[i + (1 << (j - 1))][j - 1]);
sp2[i][j] = min(sp2[i][j - 1], sp2[i + (1 << (j - 1))][j - 1]);
}
}
auto get1 = [&](int l, int r) -> int{
int k = lg[r - l + 1];
return max(sp1[l][k], sp1[r - (1 << k) + 1][k]);
};
auto get2 = [&](int l, int r) -> int{
int k = lg[r - l + 1];
return min(sp2[l][k], sp2[r - (1 << k) + 1][k]);
};
while (q--){
int s; cin>>s;
ll out = 0;
int i = left(s), j = right(s);
if (s - x[i] <= x[j] - s){
out += (s - x[i]);
s = x[i];
j = i;
}
else {
out += (x[j] - s);
s = x[j];
i = j;
}
while (i > 1 || j < n){
if (i == 1){
out += (x[n] - s);
break;
}
if (j == n){
out += (s - x[1]);
break;
}
int d1 = s - x[i - 1], d2 = x[j + 1] - s;
if (d1 <= d2){
if (s - x[1] <= x[j + 1] - s){
out += (s - x[1]);
s = x[1];
i = 1;
continue;
}
int l = 1, r = i - 1;
while (l + 1 < r){
int m = (l + r) / 2;
if (get1(m, i) > x[j + 1]){
l = m;
}
else {
r = m - 1;
}
}
if (get1(l, i) > x[j]) r = l;
out += s - x[r];
s = x[r];
i = r;
}
else {
if (x[n] - s < s - x[i - 1]){
out += (x[n] - s);
s = x[n];
j = n;
continue;
}
int l = j + 1, r = n;
while (l + 1 < r){
int m = (l + r) / 2;
if (get2(j, m) <= x[j + 1]){
r = m;
}
else {
l = m + 1;
}
}
if (get2(j, r) <= x[j]) l = r;
out += x[l] - s;
s = x[l];
j = l;
}
}
cout<<out<<"\n";
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |