题意:给你一个由n个数组成的数组,由q次查询,每次查询给你两个数,让你输出在数组中这两个数之间有有少个数。
题记:对于题目每次给出查询的两个数x和y,二分找出第一个大于y的数的下标减去第一个大于等于x的数的下标就是答案。(题目用cin会TLE)。
手写二分:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int bsearch_1(int l,int r,int x){
//找出第一个大于等于x的数,即lower_bound
while(l<r){
int mid=l+r>>1;
if(a[mid]>=x) r=mid;
else l=mid+1;
}
return l;
}
int bsearch_2(int l,int r,int x){
//找出第一个大于y的数,即upper_bopund
while(l<r){
int mid=l+r>>1;
if(a[mid]>x)r=mid;
else l=mid+1;
}
return l;
}
int main(){
int t; scanf("%d",&t);
int sum=0;
while(t--){
int n,q,x,y,pos;
scanf("%d %d",&n,&q);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
printf ("Case %d:\n", ++sum);
while(q--){
scanf("%d %d",&x,&y);
pos=bsearch_2(0,n,y);//找第一个大于y的数
pos-=bsearch_1(0,n,x);//找第一个大于等于x的数
printf("%d\n",pos);
}
}
return 0;
}
用lower_bound和upper_bound:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int main(){
int t; scanf("%d",&t);
int sum=0;
while(t--){
int n,q,x,y,pos;
scanf("%d %d",&n,&q);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
printf ("Case %d:\n", ++sum);
while(q--){
scanf("%d %d",&x,&y);
pos=upper_bound(a,a+n,y)-a;//找第一个大于y的数
pos-=lower_bound(a,a+n,x)-a;//找第一个大于等于x的数
printf("%d\n",pos);
}
}
return 0;
}