csp-出行计划-差分前缀和(详解)

问题描述(又是图片QAQ)


问题分析:

先来看差分-前缀和(真的是必看内容,不看不会,一看就会啊):

前缀和与差分 图文并茂 超详细整理(全网最通俗易懂)_林小鹿@的博客-CSDN博客_前缀和与差分

正常情况下是:站在人的角度:当前的qi 推断出地点进入的满足区间,然后遍历地点,这样做两层循环(外层是遍历qi,内层遍历所有地点)

现在反过来思考: 对于一个地方进入的时间ti  可以求出满足进入条件的 核酸检测时间边界为:  

如此:位于这个区间内的  每个数   都是   符合要求的,我们都给他    +1记一次有效次数,这样  累计了所有场景的有效次数后(每个场景都有不同的区间,叠加起来这些区间),那么当这个人在取某个数qi(也就是进入地方的时间为qi时),有几个叠加的区间,就代表能去的地方有几个。有点像这种:

 

如此,对于某个区间所有数+1的操作采用 差分-前缀和思想,就能得出下面的代码


解决方案:(差分-前缀和)

这里需要额外注意的两点是:

1.边界必须比0大吧 (就是tl tr那里)(不然整个负的算怎么回事?)

2.另外一点是 构建前缀和数组的时候 没有新开一个数组

(如果开的话 是: a[i]=a[i-1]+v[i],在这里a[i]表示前缀和数组,v[i]还是差分数组!!!!!!)

这样递推的算过来 v[i]=v[i-1] +v[i],这里的v[i]就表示前缀和数组了!!!!! ,说白了就是在原空间上直接算了!

#include<iostream>
#include<vector>
using namespace std;
int main() {
    int n, m, k;
    cin >> n >> m >> k;
    int l, r;
    vector<int> v(200010);
    for (int i = 0; i < n; i++) {
        cin >> l >> r;
        int tl = max(0, l - r - k + 1);//注意维持边界条件
        int tr = max(0, l - k);
        v[tl]++;      //精髓所在
        v[tr + 1]--;  //精髓所在
    }
    for (int i = 1; i < 200010; i++) {
        v[i] += v[i - 1]; //没开一个新的  前缀和数组,是因为没必要浪费新的空间  直接在   差分   数组上做计算就行  
    }
	//以下是为了满足输出格式
	vector<int> a;
    for (int i = 0; i < m; i++) {
        cin >> l;
        a.push_back(v[l]) ;
    }
	for(auto i  :a)
		cout<<i<<endl;
    return 0;
}

(以上内容都是个人的理解,第一次写如有不妥的地方,希望指出,可能有些csdn大大的地址也忘了给出了.....) 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值