CF1922C Closest Cities

题目传送门

codeforces

洛谷

题面 There are n cities located on the number line, the i\-th city is in the point ai. The coordinates of the cities are given in ascending order, so a1<a2<<an.

The distance between two cities x and y is equal to |axay|.

For each city i, let's define the closest city j as the city such that the distance between i and j is not greater than the distance between i and each other city k. For example, if the cities are located in points [0,8,12,15,20], then:

  • the closest city to the city 1 is the city 2;
  • the closest city to the city 2 is the city 3;
  • the closest city to the city 3 is the city 4;
  • the closest city to the city 4 is the city 3;
  • the closest city to the city 5 is the city 4.

The cities are located in such a way that for every city, the closest city is unique. For example, it is impossible for the cities to be situated in points [1,2,3], since this would mean that the city 2 has two closest cities (1 and 3, both having distance 1).

You can travel between cities. Suppose you are currently in the city x. Then you can perform one of the following actions:

  • travel to any other city y, paying |axay| coins;
  • travel to the city which is the closest to x, paying 1 coin.

You are given m queries. In each query, you will be given two cities, and you have to calculate the minimum number of coins you have to spend to travel from one city to the other city.

Input

The first line contains one integer t (1t104) — the number of test cases.

Each test case is given in the following format:

  • the first line contains one integer n (2n105);
  • the second line contains n integers a1,a2,,an (0 \le a_1 < a_2 < \dots < a_n \le 10^9);
  • the third line contains one integer m (1m105);
  • then m lines follow; the i-th of them contains two integers xi and yi (1xi,yin; xiyi), denoting that in the i-th query, you have to calculate the minimum number of coins you have to spend to travel from the city xi to the city yi.

Additional constraints on the input:

  • in every test case, for each city, the closest city is determined uniquely;
  • the sum of n over all test cases does not exceed 105;
  • the sum of m over all test cases does not exceed 105.

Output

For each query, print one integer — the minimum number of coins you have to spend.

题目大意

数线上有 n 座城市,第 i 座城市位于点 ai 。城市的坐标按升序排列。

两个城市 xy 之间的距离等于 |axay|

您可以在城市之间旅行。假设您目前在城市 x 。那么您可以执行以下操作之一:

  • 前往任何其他城市 y ,支付 |axay| 金币;
  • 前往距离 x 最近的城市,支付 1 金币。

您会收到 m 个询问。在每个查询中,您将得到两个城市,您必须计算从一个城市到另一个城市所需的最少金币数。

思路

x 走到 y ,易得最优解肯定不会出现往回走的情况,当 x<y 时,考虑记录一个“前缀和” bbi 表示从城市 1 到城市 i 的最少花费,则 x 走到 y 的最少花费即为 |bybx| (想想为什么)x>y 时同理,记录一个“后缀和”即可。

代码

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve()
{
int n, m;
cin >> n;
vector<int> a(n + 1), b(n + 1, 0), c(n + 1, 0);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
b[2] = 1; // 2号肯定是离1号最近的,所以1到2最小花费肯定是1
for (int i = 3; i <= n; i++)
{
if (a[i - 1] - a[i - 2] > a[i] - a[i - 1])
{
b[i] = b[i - 1] + 1;
// i-1最近的是i时,从i-1到i的最小花费肯定是1
}
else
{
b[i] = b[i - 1] + a[i] - a[i - 1];
// i-1最近的不是i时,从i-1到i的最小花费是|a[i-1]-a[i]|
}
}
c[n - 1] = 1; // 后缀和计算方式同上
for (int i = n - 2; i >= 1; i--)
{
if (a[i + 2] - a[i + 1] > a[i + 1] - a[i])
{
c[i] = c[i + 1] + 1;
}
else
{
c[i] = c[i + 1] + a[i + 1] - a[i];
}
}
cin >> m;
while (m--)
{
int x, y;
cin >> x >> y;
if (x < y)
cout << b[y] - b[x] << endl;
else
cout << c[y] - c[x] << endl;
}
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)
solve();
return 0;
}
posted @   Zinc_Acetate  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示