P8762 [蓝桥杯 2021 国 ABC] 123

题目描述
小蓝发现了一个有趣的数列, 这个数列的前几项如下:
1,1,2,1,2,3,1,2,3,4,…1,1,2,1,2,3,1,2,3,4,…
小蓝发现, 这个数列前 1项是整数 1 , 接下来 2 项是整数 1 至 2 , 接下来 3 项是整数 1 至 
3 , 接下来 4 项是整数 1 至 4 , 依次类推。
小蓝想知道, 这个数列中, 连续一段的和是多少

输入格式
输入的第一行包含一个整数 T, 表示询问的个数。


接下来 T 行, 每行包含一组询问, 其中第 i 行包含两个整数 l i
​和 r i, 表示 询问数列中第 l i个数到第 r i个数的和。

输出格式
输出 T 行, 每行包含一个整数表示对应询问的答案。

#include <bits/stdc++.h>
using namespace std;
long long n, l, r, ans, t1, t2, st, ed, k1, k2;

/*
前置知识点
前n项的和 (首项+末项)*项数/2  
还有就是前缀和的求解公式
不会的可以看一下这个,通俗易懂(在B站看一下)
https://www.bilibili.com/video/BV1NX4y147G5/?spm_id_from=333.337.search-card.all.click&vd_source=cb3df04c833ffa8fd0d609d3e022adb4
二分的方式求解
这个自己搜所一下

1 
1 2 
1 2 3 
1 2 3 4
......

fd求解的是这里面某个数值,使用二分的方式求解的
其他的使用图来解释
*/
//这一部分求解的是


long long fd(long long x)
{
	long long l = 1, r = 10000000, ans;
	while (l <= r)
	{
		long long mid = (l + r) / 2;
		if (mid * (mid + 1) / 2 < x)
			l = mid + 1;
		else
		{
			r = mid - 1;
			ans = mid;
		}
	}
	return ans;
}
int main()
{
	//这里是输入要看几个区间的值
	scanf("%lld", &n);
	while (n--)
	{
		//这里是看[l,r]区间的值
		scanf("%lld%lld", &l, &r);
		//这个使用二分的方式找到行的作用
		st = fd(l), ed = fd(r); 
		//这个的作用就是找到本身数字的大小的方式
		t1 = l - st * (st - 1) / 2;
		t2 = r - ed * (ed - 1) / 2;
		//这个是找前缀和的方式
		k1 = (st - 1) * st * (st + 1) / 6; //求出两个行的前缀和
		k2 = (ed - 1) * ed * (ed + 1) / 6;
		//这个用图解释一下
		cout << k2 - k1 + (t2 + 1)*t2 / 2 - (t1 - 1)*t1 / 2 << endl; //运算,把刚才处理掉的补上
	}
}

前置知识

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值