蓝桥杯 2021 国赛研究生 java 8题 123

 

之后二分查找,要知道假如你输入 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;
		}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值