复制代码
 1   
  /*第一行输入两个整数 n,m (1≤n,m≤10^5),表示姜的个数以及询问次数。
 2 第二行输入 n 个整数 a1,a2,…,an (1≤ai≤10^9),表示 n 颗姜的初始高度。
 3 接下来输入 m 行,每行两个整数 xi,yi (0≤xi≤10^18,0≤yi<n),表示两种魔法的施法次数上限。*/
 4 #include<stdio.h>
 5 #include<stdlib.h>
 6 int n, m;/*全局定义n,m*/
 7 long long Data[100005];/*全局定义姜的初始高度*/
 8 long long find[100005] = { 0 };/*全局定义寻找数组*/
 9 /*定义两种魔法次数*/
10 long long x[100005];/*单位魔法*/
11 int y[100005];/*无穷魔法*/
12 /*定义快速排序函数*/
13 int cmp(const void* a, const void* b)
14 {
15  return *(int*)a - *(int*)b;
16 }
17 /*定义寻找输出结果函数*/
18 long long Result(long long x, int y)
19 {
20  /*二分法查找*/
21  long long low, high, mid;
22  long long Flow, Fhigh, Fmid, Fmid1;
23  long long result;/*定义输出值*/
24  low = y, high = n - 1;
25  if (y == n - 1)
26  {
27   result = Data[n - 1] + x;
28  }
29  else
30  {
31   for (; low <= high;)/*构造循环寻找*/
32   {
33    mid = (low + high) / 2;
34    Fmid = find[mid] - y * (Data[mid] - Data[y]) - find[y];
35    Fmid1 = find[mid + 1] - y * (Data[mid + 1] - Data[y]) - find[y];
36    if (x >= Fmid && x < Fmid1)
37    {
38     break;/*mid为目标下标*/
39    }
40    else if (x < Fmid)
41    {
42     high = mid - 1;
43    }
44    else
45    {
46     low = mid + 1;
47    }
48   }
49   /*计算输出值*/
50   result = Data[mid] + (x - Fmid) / (mid + 1 - y);
51  }
52  return result;
53 }
54 void main()
55 {
56  /*进行数据输入*/
57  scanf("%d%d", &n,&m);/*n,m*/
58  long long i;
59  for (i = 0; i < n; i++)
60  {
61   scanf("%d", &Data[i]);/*输入姜的初始高度*/
62  }
63  /*快速从小到大对姜的高度排序*/
64  qsort(Data, n, sizeof(Data[0]), cmp);
65  /*输入m行x,y*/
66  for (i = 0; i < m; i++)
67  {
68   scanf("%lld%d", &x[i], &y[i]);
69  }
70  /*计算寻找数组中各元素的值*/
71  for (i = 1; i < n; i++)
72  {
73   find[i] = find[i - 1] + i * (Data[i] - Data[i - 1]);
74  }
75  for (i = 0; i < m; i++)
76  {
77   printf("%lld\n", Result(x[i], y[i]));
78  }
79 }
复制代码