题目描述
张经理的公司的办公室长达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; }