题解:[JOIST 2023] 比太郎之旅 / Bitaro's Travel
题意分析
首先发现,\(n,q\leq2\times 10^5\),\(\mathcal O(q)\) 肯定是不能省略的。
每一个询问其实都差不多,因此考虑如何高效的求出总旅行距离。
性质
记 \((p,q)\) 表示节点 \(p\sim q\) 的距离,即 \(\vert x_p-x_q\vert\)。
令当前起始坐标为 \(s\)。首先可以通过一次二分求出离 \(s\) 最近的节点 \(p\)。
显然,走过的节点一定是在一段连续区间内,记该区间为 \([l,r]\)。(\(l,r\) 表示节点编号)
如果打一个暴力,就会发现转向次数不会很多。
不妨令 Bitaro 上一次在 \(r\) 处向左转向走到 \(l\),在 \(l\) 处向右转向,走到 \(r+1\) 后继续向右走。
则有:
考虑反证。
假设 \((r,r+1)<(l,r)\) 成立。
则:
考虑到在 \(r\) 处是向左走走到 \(r-1\),因此 \((r-1,r)<(r,r+1)\),与上式矛盾。
故假设不成立。
这样的话,每次转向之前走的路程就是指数级增长的,则转向次数为 \(\mathcal O(\log V)\),其中 \(V\) 为坐标值域。
那就可以考虑如何快速地跳到转向的位置,可以考虑二分。
以向左走,扩展左边界寻找向右转向的位置 \(l'\) 为例。
记当前区间为 \([l,r]\)。
二分一个节点 \(p\),使得 \(x_p\geq x_l-(r+1,l)\) 且 \(p\) 最小。
-
若 \(p<l\),就代表 \(p\) 是一个可行的 \(l'\) 且是最小的 \(l'\),那么就找到了转向点。
-
否则若 \(p\geq l\),就代表不可转向,只能继续走。
但是实际上这一部分用什么都可以,ST 表倍增也可以,数据结构维护也可以。
AC 代码
时间复杂度:\(\mathcal O(q\log V\log n)\)。
其中,\(\mathcal O(\log n)\) 是二分带来的。
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
//#define DEBUG
typedef long long ll;
constexpr const int N=2e5,Q=2e5;
constexpr const ll Ans=N*1e9;
int n,q,x[N+1];
ll query(ll s){
int l,r;
l=lower_bound(x+1,x+n+1,s)-x;
l=min(l,n);
if(l-1&&s-x[l-1]<=x[l]-s){
l--;
}
ll ans=abs(x[l]-s);
r=l;
bool mode=true;//1:向左,0:向右
while(1<l&&r<n){
if(mode){
int pl=x[r+1]-x[l];
int p=lower_bound(x+1,x+n+1,x[l]-pl)-x;
if(p<l){
ans+=x[l]-x[p];
l=p;
}else{
ans+=pl;
r++;
mode=!mode;
}
}else{
int pl=x[r]-x[l-1];
int p=lower_bound(x+1,x+n+1,x[r]+pl)-x-1;
if(r<p){
ans+=x[p]-x[r];
r=p;
}else{
ans+=pl;
l--;
mode=!mode;
}
}
}
ans+=x[n]-x[1];
return ans;
}
int main(){
/*freopen("test.in","r",stdin);
freopen("test.out","w",stdout);*/
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>x[i];
}
cin>>q;
for(int i=1;i<=q;i++){
ll s;
cin>>s;
cout<<query(s)<<'\n';
}
cout.flush();
/*fclose(stdin);
fclose(stdout);*/
return 0;
}

浙公网安备 33010602011771号