Description
小wh是20级医信的助教,有一天群里大伙起哄要喝奶茶。小wh家里很有钱,他觉得给每个人只买一杯奶茶有点体现不出他的壕气,所以他打算给第i个人买ai杯奶茶。但是他班上的同学也想知道有多少个人得到的奶茶会比他多。他们一直在问作为班助的小李,小李很苦恼,于是来寻求你的帮助。
Input
输入的第一行是一个数字n,代表小李班上有n(1 <= n <= 105)个人。
接下来一行包含用空格分割开的n个数ai(1 <= ai <= 105),代表每个人可以分到ai杯奶茶。
第三行只有一个数m(1 <= m <= 105),代表小李要被问的m个学号。
下面的m行,每一行包含一个数,代表有小李问的学号k(1 <= k <= n)。
Output
对于每一次询问的k,输出从有多少个人得到的奶茶比学号为k的人得到多少的奶茶多。
Sample Input
6 2 4 1 5 1 4 4 1 2 3 4
Sample Output
3 1 4 0
HINT
Source
_____________________________________________________________________________
写在前面:这题数据量偏大,cin与cout会超时,用scanf与printf避免这个问题。这道题还可以用前缀和做。
思路:建立两个数组,一个用于记录对应学号学生喝的奶茶杯数,另一个记录上一个数组排序后的结果。(至于为什么要排序,因为可以使用二分法的序列都是提前排好序的)。读入数据并排序完毕后,利用upper_bound查找大于目标的第一个元素。
#include<bits/stdc++.h>
using namespace std;
int mt[100010];//milktea
int id[100010];
//准备两个数组 一个用于记录对应学号学生喝的奶茶杯数
//另一个用于记录上一个数组排序的结果
int main()
{
int n,m;
memset(mt,0,sizeof(mt));
memset(id,0,sizeof(id));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&id[i]);
mt[i]=id[i];
}
sort(mt+1,mt+n+1);
cin>>m;
while(m--)
{
int temp1,temp2;
scanf("%d",&temp1);
temp2=upper_bound(mt+1,mt+n+1,id[temp1])-mt;
//查找大于目标的第一个元素
printf("%d\n",n-temp2+1);
}
}