首页 > 其他分享 >二维差分·学习备忘录

二维差分·学习备忘录

时间:2024-08-12 20:39:26浏览次数:6  
标签:tsn int 差分 备忘录 二维 a2 b1 b2

二维差分

为什么我为OI泪目?因为我菜得离谱......

引入

一维差分用来O(1)修改区间,配合上一维前缀和就是O(N)的查询区间和。
差分为前缀和的逆运算。
二维差分同理。
接下来这道题就用二维差分来解决。

\(例题:地毯>>\)

地毯

题目描述

在 \(n\times n\) 的格子上有 \(m\) 个地毯。

给出这些地毯的信息,问每个点被多少个地毯覆盖。

输入格式

第一行,两个正整数 \(n,m\)。意义如题所述。

接下来 \(m\) 行,每行两个坐标 \((x_1,y_1)\) 和 \((x_2,y_2)\),代表一块地毯,左上角是 \((x_1,y_1)\),右下角是 \((x_2,y_2)\)。

输出格式

输出 \(n\) 行,每行 \(n\) 个正整数。

第 \(i\) 行第 \(j\) 列的正整数表示 \((i,j)\) 这个格子被多少个地毯覆盖。

样例 #1

样例输入 #1
5 3
2 2 3 3
3 3 5 5
1 2 1 4
样例输出 #1
0 1 1 1 0
0 1 1 0 0
0 1 2 1 1
0 0 1 1 1
0 0 1 1 1

提示

样例解释

覆盖第一个地毯后:

\(0\) \(0\) \(0\) \(0\) \(0\)
\(0\) \(1\) \(1\) \(0\) \(0\)
\(0\) \(1\) \(1\) \(0\) \(0\)
\(0\) \(0\) \(0\) \(0\) \(0\)
\(0\) \(0\) \(0\) \(0\) \(0\)

覆盖第一、二个地毯后:

\(0\) \(0\) \(0\) \(0\) \(0\)
\(0\) \(1\) \(1\) \(0\) \(0\)
\(0\) \(1\) \(2\) \(1\) \(1\)
\(0\) \(0\) \(1\) \(1\) \(1\)
\(0\) \(0\) \(1\) \(1\) \(1\)

覆盖所有地毯后:

\(0\) \(1\) \(1\) \(1\) \(0\)
\(0\) \(1\) \(1\) \(0\) \(0\)
\(0\) \(1\) \(2\) \(1\) \(1\)
\(0\) \(0\) \(1\) \(1\) \(1\)
\(0\) \(0\) \(1\) \(1\) \(1\)

数据范围

对于 \(20\%\) 的数据,有 \(n\le 50\),\(m\le 100\)。

对于 \(100\%\) 的数据,有 \(n,m\le 1000\)。

题解

康康数据范围,\(n<=1000\),暴力修改\(O(n^ 2)\),共有\(O(m)\)次修改,总共\(O(n^2*m)=1e9\)复杂度,洛谷能够过,但\(CCF\)肯定会把你卡死。
于是出现吧:二维差分!
首先拿来一张图,要让红色部分+1,如何\(O(1)\)解决?
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

0 0 0 0
0 0(x1,y1) 0 0
0 0 0(x2,y2) 0
0 0 0 0
差分是为了后面的前缀和做准备
我们先给\((x1,y1)+1\),可以达成增加的目的,但事情就会成这样(前缀和之后)
0 0 0 0
0 1 1 1
0 1 1 1
0 1 1 1

很显然,蓝,绿,棕四个部分都是被多加了的
于是我们再给\((x1,y2+1)-1,(x2+1,y1)-1\)来抵消影响。
但……
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 -1
这里会被减两遍
再给其+1就OK

如果遇到差分数组要初始化的情况,例如第2题,我们就将它当做边长为1的矩形差分处理即可。

CODE

#include<bits/stdc++.h>
using namespace std;
const int tsn=1e3+5;

int n,m;
int qz[tsn][tsn];
int sum[tsn][tsn];

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("00in.txt","r",stdin);
        freopen("00out.txt","w",stdout);
    #endif
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int a1,b1,a2,b2;
        cin>>a1>>b1>>a2>>b2;
        qz[a1][b1]++,qz[a1][b2+1]--,qz[a2+1][b1]--,qz[a2+1][b2+1]++;
    }
    // for(int i=1;i<=n;i++,cout<<endl)
    //     for(int j=1;j<=n;j++)
    //         cout<<qz[i][j]<<" ";cout<<endl;
    for(int i=1;i<=n;i++,cout<<endl)
        for(int j=1;j<=n;j++)
            sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+qz[i][j],cout<<sum[i][j]<<" ";
    return 0;
}


【模板】二维差分

题目描述

给你一个n行m列的矩阵,下标从1开始。

接下来有q次操作,每次操作输入5个参数x1, y1, x2, y2, k

表示把以(x1, y1)为左上角,(x2,y2)为右下角的子矩阵的每个元素都加上k,

请输出操作后的矩阵。

输入格式

第一行包含三个整数\(n,m,q\).

接下来\(n\)行,每行\(m\)个整数,代表矩阵的元素

接下来\(q\)行,每行5个整数\(x1, y1, x2, y2, k\),分别代表这次操作的参数

输出格式

输出n行,每行m个数,每个数用空格分开,表示这个矩阵。

样例 #1

样例输入 #1
2 3 4
1 2 3
4 5 6
1 1 2 2 3
1 2 2 3 -1
1 1 1 3 4
1 1 2 1 1
样例输出 #1
9 8 6
8 7 5

提示

\(1≤n,m≤1000\)

\(1≤q≤10^5\)

\(1≤x1≤x2≤n\)

\(1≤y1≤y2≤m\)

\(−10^9≤矩阵中的元素≤10^9\)

\(−10^5≤k≤10^5\)

分析

注意一下上文,对你来说不是难事。

CODE

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int tsn=1e3+5;

int n,m,q;
int a[tsn][tsn];
int cf[tsn][tsn];
int sum[tsn][tsn];
void _cf(int a1,int b1,int a2,int b2,int k)
{
    cf[a1][b1]+=k,
    cf[a2+1][b1]-=k,
    cf[a1][b2+1]-=k,
    cf[a2+1][b2+1]+=k;
}
signed main()
{
    #ifndef ONLINE_JUDGE
        freopen("00in.txt","r",stdin);
        freopen("00out.txt","w",stdout);
    #endif
    
    int n,m,q;
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j],_cf(i,j,i,j,a[i][j]);
    while(q--)
    {
        int a1,b1,a2,b2,k;
        cin>>a1>>b1>>a2>>b2>>k;
        _cf(a1,b1,a2,b2,k);
    }
    for(int i=1;i<=n;i++,cout<<endl)
        for(int j=1;j<=m;j++)
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+cf[i][j],cout<<sum[i][j]<<" ";
    return 0;
}

完结撒❀

在这里插入图片描述
在这里插入图片描述

图片来自网络。

标签:tsn,int,差分,备忘录,二维,a2,b1,b2
From: https://www.cnblogs.com/happy-salted-fish/p/18355700

相关文章

  • 差分约束 笔记
    差分约束笔记给定约束\(n\)个未知数的\(m\)个约束条件,求满足条件的未知数的其中一个整数解。\(m\)个约束条件如下:\[\left\{\begin{matrix} x_{c_1}+w_1\gex_{c'_1}\\ x_{c_2}+w_2\gex_{c'_2}\\ x_{c_3}+w_3\gex_{c'_3}\\ \dots\\ x_{c_m}+w_m\ge......
  • C语言学习心得-二维数组
    (一)二维数组的定义和初始化定义二维数组arr[3][5]:intarr[3][5]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};仔细看这个数组arr[0] 是第一个一维数组,包含元素 arr[0][0],arr[0][1],arr[0][2],arr[0][3],arr[0][4]arr[1] 是第二个一维数组,包含元素 ......
  • 二维前缀和学习指南
    为什么我为OI泪目,因为我菜得离谱......二维前缀和引子二维前缀和,仅仅是由一维前缀和进阶了一维而已。为了方便后面的学习,我先给出二维前缀和重点代码。处理二维前缀和for(inti=1;i<=n;i++) for(intj=1;j<=m;j++) sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[......
  • 练习讲解--手动为二维数组的每个元素赋值
    importjava.util.*;publicclassA{publicstaticvoidmain(String[]args){Scannerinput=newScanner(System.in);int[][]nums=newint[3][4];for(inti=0;i<nums.length;i++){for(intj=0;j<nums[i].lengt......
  • 第七章 二维数组
    文章目录第七章二维数组1.冒泡排序2.使用Arrays为数组排序3.二维数组第七章二维数组1.冒泡排序每次比较相邻两数小的交换到前面每轮结束后最大的数交换到最后5个数字如何存放数组,数组.length=5控制比较多少轮外层循环,循环变量i控制每轮比较多少次内......
  • 【408DS算法题】009进阶-二维数组的查找
    Index题目实现代码分析题目在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。​进阶要求——时间复杂度:......
  • BUUCTF 81题吹着贝斯的二维码详解(包含各类工具和python脚本)
    在网上看了很多类似解题步骤和说明,感觉对小白都不友好,于是决定搜集整理下,做个详尽的解题步骤:压缩包解压得到36个无后缀名文件和一个flag.zip压缩包再看压缩包,解压发现有压缩密码,用winhex查看是不是伪加密,在末尾发现一串可疑字符串,拷贝下来留用:GNATOMJVIQZUKNJXGRCTGNRTG......
  • 初始化二维vector
    这里是我遇到的一些对于二维vector容器初始化的一些问题的总结与记录,一共有一下四种情况,随时添加新的方式方法。初始化一个二维vector,行M,列N//初始化一个二维的matrix,行M,列N,且值为0vector<vector<int>>matrix(M,vector<int>(N));//等价于下面的vector<vector<......
  • 编写类 MyTools 类,编写一个方法可以打印二维数组的数据。 2) 编写一个方法 copyPerson
    1publicclassMethodExercise02{2publicstaticvoidmain(String[]args){34Personp=newPerson();5p.name="milan";6p.age=100;7//创建tools8MyToolstools=newMyTools();9......
  • java 生成 二维码
    ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。Zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码。导入对应的jar包<dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <v......