题目描述:
多次查询[l,r]范围内的完全平方数个数
定义整数x为完全平方数当且仅当可以找到整数y使得y*y=x
输入:
先输入一个整数N,接下来N行,每行输入一个范围;
输出:
一个整数,范围中的完全平方数的个数;
思路:
我们需要的是l,r之间能够开方并且开方结果为整数的数,那么我们就可以反其道而行之,把l,r分别开方,求之间的整数的个数即可;虽然:我们可以使用stl中的upper_bound以及lower_bound直接进行运算,但是为了锻炼自己的代码能力所以还是自己手打一下这两个函数吧;
因为按照题目来的,所以我写的lower与upper与stl中的有所差异。
lower:
int lower(int l,int r,int number){
int mid=(l+r)>>1;
while(l<=r){
mid =(l+r)>>1;//mid要随l,r的变化而更新;
if(mid>=number) r=mid-1;//因为找的是最左边的该数值,所以即使等于也要左移,直到最左边为止。
else {
l=mid+1;
}
}
return l;
} upper
类似于lower就不做过多解释了;
int upper(int l,int r,int number){
// cout<<number<<endl;
int mid =(l+r)>>1;
while(l<=r){
mid =(l+r)>>1;
if(mid>number)r=mid-1;
else{
l=mid+1;
}
}
return l;
}最后就是AC代码了
#include<iostream>
#include<cmath>
using namespace std;
const int type=36125;
int lower(int l,int r,int number){
int mid=(l+r)>>1;
while(l<=r){
mid =(l+r)>>1;
if(mid>=number) r=mid-1;
else {
l=mid+1;
}
}
return l;
}
int upper(int l,int r,int number){
int mid =(l+r)>>1;
while(l<=r){
mid =(l+r)>>1;
if(mid>number)r=mid-1;
else{
l=mid+1;
}
}
return l;
}
int main(){
int n;
cin>>n;
while(n--){
int x,y;
cin>>x>>y;
int L,R;
if(x-(int)sqrt(x)*(int)sqrt(x)>0){
L=upper(0,type,sqrt(x));
}else{
L=lower(0,type,sqrt(x));
}
R=upper(0,type,sqrt(y));
int ans = max (R-L,0);
cout<<ans<<endl;
}
return 0;
}笱蒻一枚,有错请指教

京公网安备 11010502036488号