• 区间修改的离线查询——差分数组


    差分数组这样的优化表示方法十分常见

    • 如果我们假设有一列数a[1],a[2],a[3]...

    • 那么若这样的差分数组表示为d[1],d[2],d[3]...

    • 则有d[1]=a[1];

    • d[2]=a[2]-a[1];

    • d[3]=a[3]-a[2];

    //一般我们也可以假设一个a[0]=0,就可以和下面的一样了

    ...

    差分数组应用很多,不过大部分都需要具体题目具体分析

    但是在区间修改的离线查询中,差分数组是一个很优秀的线性算法

    E.G. 题目描述链接

    宾馆房间 hotelroom

    (这里题目描述我就简略了写了)

    2180年奥运会竞技类分会场,将在XX市举行。会场自然是政府的事情,我们就别操心了。艾瑞克却被兴奋而苦恼的情绪折磨着,他的宾馆是XX市最好的宾馆,近期旅客投宿的订单m份接踵而至,时间从1~n天,这代表着大把大把的银子,可是他最多只能提供k间客房,更多的他只能提前去租附近的房子并赶紧装修一下,时间很紧啊。

    艾瑞克找到了他最好的朋友你:“哪,这是所有的订单,你给我在1s内计算出最高峰时,超出多少间客房,这样我才能知道得去租多少房子啊。”

    每张订单包含dj,sj,tj:表示从第sj日至第tj日,预定房间dj间。

    【输入描述】:

    第一行包含两个正整数n,m,k,表示天数、订单的数量,和现有客房数。
    接下来有m行,每行包含三个正整数dj,sj,tj,表示租借的数量,租借开始、结束分别在第几天。
    每行相邻的两个数之间均用一个空格隔开。天数与订单均用从1开始的整数编号。
    

    【输出描述】:

    只有一个整数,表示最高峰时还差多少客房,客房足够输出0(骗不到分)。
    

    【样例输入】:

    4 3 6
    2 1 3
    3 2 4
    4 2 4
    

    【样例输出】

    3
    

    【数据范围及描述】:

    1<=n,m<=1000,000;1<=sj<=tj<=n;1<=k,dj<=1000
    

    下面讲解原理:

    (1)我们设sum[i]为d[i]的前缀和

    那么显然sun[i]=a[i]

    (2)在区间修改的时候如果我们直接对整个区间进行操作,那么复杂度将会非常高

    当然我们可以使用线段树等工具来优化,但是还是很慢

    那如果有机会每一次修改的时候都只改单个数据(或两个数据),那该有多好?

    所以,如果我们需要在[l,r]中都加上x的话

    只需要d[l]+=x,d[r+1]-=x; //(自己想想为什么)

    然后这道题就迎刃而解了

    我们只需要每一次修改时对d数组处理两次,然后最后查询的时候先用d[]把a[]算出来,最后直接离线O(1)查询

    代码片段:

        for(int i=1;i<=m;i++){
    	d=read();s=read();j=read();
    	a[s]+=d;a[j+1]-=d;
        }
        for(int i=1;i<=n;i++){
    	sum+=a[i];
            ans=max(ans,sum-k);
        }
        printf("%d",ans);
    

    还有就是稍微注意一下读入优化,这种题目当心一点

    That's all.

  • 相关阅读:
    学点 C 语言(40): 函数 多参函数
    存取 ListBox 列表 回复 "徐强" 的问题
    博客园RSS订阅汇总
    博客园电子期刊2012年2月刊发布啦
    上周热点回顾(3.53.11)
    博客园电子期刊2012年3月刊发布啦
    上周热点回顾(3.264.1)
    上周热点回顾(3.193.25)
    上周热点回顾(4.24.8)
    上周热点回顾(2.273.4)
  • 原文地址:https://www.cnblogs.com/battlin/p/12243063.html
Copyright © 2020-2023  润新知