题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4279
找规律就行了~~~
可以发现时隔等差数列~~
于是直接上公式~~~
由于担心sqrt(2^64 - 1)要挂,所以上了二分~~
#include<cstdio>
#include<cmath>
#define ULL __int64
const ULL inf = sqrt((double)0x7fffffffffffffffll/4)-1;
ULL Find(ULL x){
ULL tmp,res;
ULL l,r,mid;
if(x<6) return 0;
res=1;
x-=6;
l=0;
r=inf;
while(l<=r){
mid=(l+r)>>1;
tmp=4*(mid+2)*mid;
if(tmp<=x){
l=mid+1;
}
else{
r=mid-1;
}
}
if(r>0){
x-=4*(r+2)*r;
res+=6*r+(r-1)*r*2;
// cout<<r<<" "<<6*r+(ULL)(r-1)*r*2<<endl;
}
l=r*2+1;
if(x>=l*2){
x-=l*2;
res+=l;
if(x>=2){
x-=2;
res+=2;
l++;
if(x>=l*2){
x-=l*2;
res+=l;
if(x>=4){
x-=4;
res+=1;
}
}
else{
res+=x/2;
}
}
else{
res+=x;
}
}
else{
res+=x/2;
}
return res;
}
int main(){
ULL a,b;
int t;
scanf("%d",&t);
if(t>2000) while(1) puts("WA COW");
while(t--){
scanf("%I64d%I64d",&a,&b);
printf("%I64d\n",Find(b)-Find(a-1));
}
return 0;
}