【二维差分】洛谷P3997地毯
群里的大佬都去Online#3的提高组了,就蒟蒻(我)一个人报了普及组,做做前缀和与差分的题聊以慰籍
题目传送门
前言
这道题在洛谷上wxz大佬的题解已经说得很清楚了(自己给自己出的题写题解),虽然题目说难度在Day2T1,但是那个1e3的数据范围刚好可以枚举,所以各种玄学暴力做法都能过。蒟蒻把自己做这道题的思路还有对差分的一些(浅薄的)理解整理下来,有不当之处欢迎各位大佬评论指出~
解题思路
这道题本质上可以这样理解:
给定一个矩阵,每个位置初始是0,现在给定若干个可能重叠的子矩阵,每个子矩阵的覆盖区域加上1,最后输出整个矩阵。
我们把每个子矩阵拆成若干行,然后一个子矩阵就转换为若干个长度相同的子段,也就转化成了一维的差分。最后扫描一遍,根据标记输出就行了。
上面是大概的思路,下面本蒟蒻会从一维差分梳理到这道题的代码,各位大佬可以直接去看最下面的代码。
一维差分
想要做差分的题,先要理解差分到底有什么用,最常见的差分题目就是:
给定一个序列,初始化为0,然后对其进行m次操作:
每次操作给出该序列的一个子段[L,R],这个子段内的所有元素+1
最后要求你输出整个序列。
没有学过差分的话,看到题目可能会对每一个[L,R],遍历它,然后每个元素都+1。虽然可以得到答案,但是复杂度是O(n*m),要是n是10e6,10e7,基本就妥妥的TLE了。这个时候就要用到差分的思想:在区间的首尾打上标记,输出的时候根据标记输出对应的值就得到最终答案,这里举个例子让大家更好的明白:
假设序列长度为10,3次操作给定区间是[2,8],[4,6],[1,3]。
第一次我们在2处打上标记(+1),9处打上标记(-1),在9处打上标记是因为8还属于这个子段,到9才离开。数组为:
0 1 0 0 0 0 0 0 -1 0
第二次在4处打一个标记,7处也打一个
0 1 0 1 0 0 -1 0 -1 0
第三次在1和4处打上标记:
1 1 0 0 0 0 -1 0 -1 0
如果我们不在末尾打上标记,就不知道这个子段到哪里结束,有人说:那把子段每一个元素都打上标记不就知道了?可以,但是那就变成了暴力枚举了,没有任