题目描述
张经理的公司的办公室长达100000米,从最左端开始每间隔1米都有一个工位(从第1米开始有工位),位于第i米的工位称为i号工位,且这些工位都在一条水平线上。他有n个员工,每个员工分别位于xi号工位上(不同员工可能位于同一个工位)。
现在张经理想把员工聚集在某两个工位上,他有q套方案(每套方案包含两个工位号,两个工位号可能相同),他想知道对于每套方案,所有员工都到达两个工位中的某一个所需走的最短路径之和是多少。
输入描述:
第一行输入两个正整数n, q
第二行输入n个正整数xi,分别代表第i个员工的工位
之后q行每行输入两个整数a,b,代表该套方案要求的两个集合位置
(1<=n,q,xi,a,b<=10^5)
输出描述:
对于每套方案,输出一个整数代表答案,每个答案独占一行。
示例输入:
3 2 1 3 5 1 4 2 1
示例输出:
2 4
算法思想:
参考资料
张经理的员工---------------------------思维(前缀和)
扩展资料
参考代码:
#include<iostream>
#define LEN 100001
using namespace std;
int site[LEN];//当前工位号下的员工数
int sum1[LEN];//工位号的前缀和
int sum2[LEN];//员工数的前缀和
int main(){
int n,q;//n个员工,q套方案
cin >> n >> q;
/*记数排序方式输入*/
for(int i=0;i<n;i++){
int temp;
cin >> temp;
site[temp]++;//工位号"temp"下的员工数+1
}
/*前缀和处理*/
for(int i=1;i<=LEN;i++){
sum1[i]=sum1[i-1]+site[i]*i;
sum2[i]=sum2[i-1]+site[i];
}
while(q--){
int a,b;//代表该套方案要求的两个集合位置
cin >> a >> b;
if(a>b)
swap(a,b);//保证a<=b
int mid=(a+b)/2;//二分法
int path=0;//路径长度初始化
/*1~a*/
path+=sum2[a]*a-sum1[a];
/*a~mid*/
path+=(sum1[mid]-sum1[a])-(sum2[mid]-sum2[a])*a;
/*mid~b*/
path+=(sum2[b]-sum2[mid])*b-(sum1[b]-sum1[mid]);
/*b~LEN*/
path+=(sum1[LEN]-sum1[b])-(sum2[LEN]-sum2[b])*b;
cout << path << endl;
}
return 0;
} 
京公网安备 11010502036488号