一维差分和二维差分

差分

一维:

原数组:\(c[i]\)

差分数组\(a[i]\):表示\(i{\sim}n\)的数,每一个数\(c[j](i<=j<=n)\)都加上一个\(a[i]\)

应用场景:

①把从第\(k~n\)位的数都加上一个\(w\)

a[k]+=w;

②把从第\(i\)位到第\(j\)位的数都加上一个\(w\)

a[i]+=w,a[j+1]-=w;

前提是需要对数组,进行多次①②这样的操作,使用差分才有意义,不然直接暴力就可以了

要注意的是①②操作只是把那些加减操作缓存了起来,而并不是完全分布给了每一个\(c[i]\)

要把这些加减操作“落到实处“

for(int i=1;i<=n;++i)
{
  a[i]+=a[i-1];
  c[i]+=a[i];
  a[i]=0;
}

二维:

原数组:\(c[n][m]\)

差分数组:\(a[i][j]\),表示在\((i<=x<=n,j<=y<=m)\)范围内的数都加个\(a[i][j]\)

应用场景:

①把\((i<=x<=n,j<=y<=m)\)内的数都加上个\(k\)

a[i][j]+=k;

②把\((x_1<=x<=x_2,y_1<=y<=y_2)\)的数都加上\(k\)

a[x1][y1]+=k,a[x2+1][y2+1]+=k;
a[x1][y2+1]-=k,a[x2+1][y1]-=k;

把差分的操作下放到\(c[i][j]\)数组中:

for(int i=1;i<=n;++i)
  for(int j=1;j<=m;++j)
      a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1],
      c[i][j]+=a[i][j];

原文地址:https://www.cnblogs.com/CADCADCAD/p/12182598.html

时间: 2024-10-14 21:44:03

一维差分和二维差分的相关文章

二维差分

二维差分和一维差分思路上并没有什么区别,具体实现的区别就在于一维的直接对区间两端差分就好了,而二维的多了一维需要处理. 差分的思想是和前缀和有关的,一维的前缀和我们都懂求,那么二维的呢? 如图 因为是从左到右,从上到下的遍历,当要求红色部分,(0,0)到(i,j)处的前缀和时,我们黄色部分和蓝色部分已经是已知的了,而它们重叠的部分就是绿色部分,所以把黄色和蓝色部分的结果加起来,再减去绿色部分,最后加上(i,j)处的值就是(i,j)位置的前缀和了. 所以,二维前缀和就是sum[i][j]=a[i]

Gym 102028J 扫描线/二维差分 + 解方程

题意:有一个二维平面,以及n个操作,每个操作会选择一个矩形,使得这个二维平面的一部分被覆盖.现在你可以取消其中的2个操作,问最少有多少块地方会被覆盖? 思路:官方题解简洁明了,就不细说了:https://codeforces.com/blog/entry/63729. 此处重点记录一下两种做法的巧妙之处. 1:二维差分+解方程 二维差分:假设在矩形[(x1, y1), (x2, y2)]上加一个数,那么在(x1, y1), (x2 + 1, y2 + 1)加1, (x1, y2 + 1), (x

Codeforces Round #578 (Div. 2) 二维差分 可做模板

题意: 在n*n的矩阵中,你可以选择一个k*k的子矩阵,然后将这个子矩阵中的所有B全部变为W,问你怎么选择这个子矩阵使得最终的矩阵中某一行全是W或者某一列全是W的个数最多 题解:考虑每一行和每一列,对于特定的一行来说,要想让其全变为W,那么子矩阵的左上角端点是在一个范围中的,因此我们可以把范围中的每一个值加1 为了速度选择用二维差分来做,最终矩阵中的最大值就是答案 此题可以作为二维差分模板 #include<bits/stdc++.h> #define forn(i, n) for (int

java数组(一维数组,二维数组)

数组初始化: 1,动态初始化:数组定义与为数组分配空间和赋值的操作分开进行 2,静态初始化:在定义数组的同时就为数组元素分配空间并赋值 3,默认初始化:数组是引用类型,它的元素相当于类的成员变量,因此,数组分配空间之后 每个元素也被按照成员的规则被隐士的初始化值 ------------------------------------------------. 一维数组: package day06; import java.util.Date; /*** * 数组演示 * 数组的声明: * t

C#一维数组,二维数组,多维数组

所谓的数组,就是相同数据类型的元素的元素按一定顺数排列的集合,就是把有限个类型相同的变量用一名字命名,然后用编号区分他们的变量的集合,这个名字成为数组名,编号称为下标.组成数组的各个变量成为数组的分量,也称为数组的元素,有时也称为下标变量,数组是在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种形式.这些按序排列的同类数据元素的集合成为数组. 数组又分为一维数组,二维数组,多维数组 一维数组用一个整数来索引,多维数组用两个或多个整数来索引. 一.数据类型[] 变量名

16.10.20 4th 1蛤蟆爬井 2一维数组 3二维数组

摘要 1蛤蟆爬井 2一维数组 3二维数组 例子 井深10米, 蛤蟆白天爬5m,晚上落4米,求几天爬出来. //思路,用循环语句来做,for因为是未知次数所以排除,while 先判断后运行排除, dowhile,先爬在判断所以可以 int gaodu = 0; int tianshu = 0; boolean tianse = true; do{ if(tainse){ //白天爬5米 gaodu+=5; //爬完后改黑天 tianse = false; //天数+1 tianshu +=1; }

ZXing拍码后区分扫描到的是一维码、二维码、其他码

以前没有怎么接触过二维码,最近遇到一个问题,如何判断条码扫描到的是一维码还是二维码,经过自己艰苦奋斗一下午,加上网上查询资料, 总结出两种方式可以解决该问题(推荐采用第二种方式): 1.修改源码(具体后面会提到) 2.通过返回的编码来判断 实现方式一: 源码的修改,关键涉及到三个类,CaptureActivity.DecodeThread.DecodeFormatManager 1.首先让我们来看下Zxing的源码,里面有一个DecodeFormatManager编码管理类:该来原本的final

一维数组,二维数组,三维数组,数组与指针,结构体数组,通过改变指针类型改变访问数组的方式

 打印数组中的每个元素,打印每个元素的地址: #include <stdio.h> #include <stdlib.h> void main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; for (int *p = a; p < a + 10;p++)  //指针类型决定4个字节 { printf("\n%p,%d", p, *p); } getchar(); } 指针数组 #inclu

C# 数组、一维数组、二维数组、多维数组、锯齿数组

C#  数组.一维数组.二维数组.多维数组.锯齿数组 一.数组: 如果需要使用同一类型的对象,就可以使用数组,数组是一种数据结构,它可以包含同一类型的多个元素.它的长度是固定的,如长度未知的情况下,请使用集合. 二.一维数组: 声明及初始化: class Program { static void Main(string[] args) { //方法一 int[] num = new int[3];//声明一个长度为3的值类型的数组: num[0] = 3;//为数组赋值: num[1] = 5