【蓝桥杯国赛真题】123


一、题目

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、解法分析

我用的方法是前缀和+二分。创建一个vector,用来记录数量的前缀和,例如0、1、3、6、10。再创建一个map,用来记录对应于每一个数量的前缀和,例如对应上面的,那就是0、1、4、10、20。(即0、0+1、0+1+1+2、0+1+1+2+1+2+3、0+1+1+2+1+2+3+1+2+3+4)。用题目所给的范围把map和vector初始化好之后,就可以进行t次的查询了。我的方法是这样:举个例子,题目某次查询为5、8,那么我们通过lower_bound找到vector中大于等于5的第一个数,即6;再通过同样的方式找到vector中大于等于8的第一个数,即10。然后为了求出5~8的区间和,我将10的前一个数(即6)的前缀和(即10)减去6的前一个数(即3)的前缀和(即4),然后减去(5-3-1)(1+5-3-1)/2,再加上(8-6)(1+8-6)/2。得出结果为10-4-1+3=8。下面这张图能很好得解释这种做法。
在这里插入图片描述

三、代码

#include <bits/stdc++.h>

using namespace std;
int t;
long long sumed=0;
long long sum2;
map<long long,long long>a;
vector<long long>b;
int main()
{
    long long l;
    long long r;
    long long i=1;
    long long sum=0;
    b.push_back(0);
    a[0]=0;
    while(1)
    {
        if(sumed>=1000200000000)
        {
            break;
        }
        sumed=sumed+i;
        b.push_back(sumed);
//        printf("%lld\n",sumed);
        sum=sum+(1+i)*i/2;
        a[sumed]=sum;
//        printf("%lld\n",sum);
        i++;
        }
        cin>>t;
        while(t--)
        {
            cin>>l;
            cin>>r;
            int s1=lower_bound(b.begin(),b.end(),l)-b.begin();
            int s2=lower_bound(b.begin(),b.end(),r)-b.begin();
            sum2=a[b[s2-1]]-a[b[s1-1]];
            long long c1=(l-b[s1-1]-1)*(1+l-b[s1-1]-1)/2;
            long long c2=(r-b[s2-1])*(1+r-b[s2-1])/2;
            sum2=sum2-c1+c2;
            printf("%lld\n",sum2);
            }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值