之后二分查找,要知道假如你输入 6 这个比较特殊的数字 他就是等于 a[3] ,10的话等于a[4],那
么如果你输入的数字是7-10直接那就是肯定会进入a[4]的管辖范围。这也就是二分查找的意义,就
是看看他到谁的管辖范围。假设你输入的数字是9 ,你想知道结果是多少,首先他会大于a[3]的管
辖范围,那么得到的结果要加上s[3] (注意:a[3]恰好等于a[3]范围最后一个元素下标6,a[4]恰好等于a[4]范围最后一个元素下标10,a[5]恰好等于a[5]范围最后一个元素下标15。。。。,所以要用a[]来查找输入元素所属范围位置,进而确定s[]),确定是s[3]了,然后加上a[(int)(i - a[l])]也就是补充一下多出a[3]范围的部分,看看和是多少i-a[l]就是看看多出几个,多出2个就是a[2]确定和(1+2)
static int maxn = 1414215;//最大的值,因为 整数T是不大于 1e12的
static long a[] = new long[maxn];
static long s[] = new long[maxn];
static long preSum(long i) {//2分查找,查到那个数列
int l = 0, r = maxn , mid;
while(l<r) {
mid = (l + r + 1 )/ 2;
if(a[mid] > i) r = mid - 1;
else l = mid;
}
return s[l] + a[(int)(i - a[l])]; //s[l],代表前l个数列的和,那么在s[l]的基础上应该继续加上a[(int)(i-a[l])],
//换句话说就是比s[l]还要多 a[(int)(i-a[l])]这些
}
public static void main(String[]args) {
for(int i = 1;i<maxn;i++) {
a[i] = a[i - 1] + i;//就是到第i个数列的所以元素的和
s[i] = s[i - 1] + a[i];//前i个数列的元素总和
}
int t;
Scanner scan = new Scanner(System.in);
t = scan.nextInt();
while(true) {
long l,r;
l = scan.nextLong();
r = scan.nextLong();
System.out.println(preSum(r)-preSum(l-1));//右边的和减去左边的,记住是 l - 1因为不需要减去其本身的值
t--;
if(t<1)
break;
}
}