pat 1046 Shortest Distance(20 分) (线段树)

时间:2023-12-05 11:22:44
1046 Shortest Distance(20 分)

The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.

Input Specification:

Each input file contains one test case. For each case, the first line contains an integer N (in [3,10​5​​]), followed by N integer distances D​1​​ D​2​​ ⋯ D​N​​, where D​i​​ is the distance between the i-th and the (i+1)-st exits, and D​N​​ is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (≤10​4​​), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than 10​7​​.

Output Specification:

For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.

Sample Input:

5 1 2 4 14 9
3
1 3
2 5
4 1

Sample Output:

3
10
7
 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#define LL long long
using namespace std;
const int MAX = 4e5 + ; int N, D[MAX], pre[MAX], M, ans, a, b, ans2;
struct node
{
int L, R, val;
}P[MAX]; void build(int dep, int l, int r)
{
P[dep].L = l, P[dep].R = r, P[dep].val = ;
if (l == r)
{
pre[l] = dep;
return;
}
int mid = (l + r) >> ;
build(dep << , l, mid);
build((dep << ) + , mid + , r);
} void update(int r, int b)
{
P[r].val += b;
if (r == ) return ;
update(r >> , b);
} void query(int dep, int l, int r)
{
if (P[dep].L == l && P[dep].R == r)
{
ans += P[dep].val;
return ;
}
int mid = (P[dep].L + P[dep].R) >> ;
if (r <= mid) query(dep << , l, r);
else if (l > mid) query((dep << ) + , l, r);
else
{
query(dep << , l, mid);
query((dep << ) + , mid + , r);
}
} int main()
{
// freopen("Date1.txt", "r", stdin);
scanf("%d", &N);
build(, , N);
for (int i = ; i <= N; ++ i)
{
scanf("%d", &D[i]);
update(pre[i], D[i]);
} scanf("%d", &M);
while (M --)
{
ans = ;
scanf("%d%d", &a, &b);
if (b < a) swap(a, b);
if (a == b - ) ans += D[a];
else query(, a, b - );
ans2 = ans, ans = ; if (a - == ) ans += D[];
else if (a - > ) query(, , a - );
if (b == N) ans += D[N];
else query(, b, N);
printf("%d\n", min(ans, ans2));
}
return ;
}