题目背景
此题约为NOIP提高组Day2T1难度。

题目描述
在n*n的格子上有m个地毯。

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

输入输出格式
输入格式:
第一行,两个正整数n、m。意义如题所述。

接下来m行,每行两个坐标(x1,y1)和(x2,y2),代表一块地毯,左上角是(x1,y1),右下角是(x2,y2)。

输出格式:
输出n行,每行n个正整数。

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

输入输出样例
输入样例#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 0 0 0 0 0 1 1 1 0
0 1 1 0 0 0 1 1 0 0 0 1 1 0 0
0 1 1 0 0 -> 0 1 2 1 1 -> 0 1 2 1 1
0 0 0 0 0 0 0 1 1 1 0 0 1 1 1
0 0 0 0 0 0 0 1 1 1 0 0 1 1 1
数据范围

对于20%的数据,有n<=50,m<=100。

对于100%的数据,有n<=1000,m<=1000。
【題意】:略
【分析】://by阮行止

n*n的矩阵,每次给一个子矩阵 区间+1 。最后输出整个矩阵。优化。用二维线段树或二维树状数组完成上面的操作。足以吊打此题。但是NOIP是不会考二维数据结构的考虑这个问题的一维版:一个序列,最开始全是 0 .每次区间加 1 ,最后输出每个数。于是有一种叫做“差分”的奇技淫巧:假设我们现在要给[2,5]这个区间加一。原来的序列是:0 0 0 0 0 0 0 0这时候我们在2上面打 +1 标记, 6 上面打 -1 标记。那么现在的序列是:0 +1 0 0 0 -1 0有什么用呢?从左往右扫描这个数组,记录当前经过的标签之和。这个和就是对应那个数的答案。这样,对于每个区间加操作,只需要O(1) 的时间打上标记。最后扫描输出即可。现在把问题拓展到二维。假设我们要覆盖[(2,2),(5,5)] ,那么标记便可以这样打:0 0 0 0 0 0
0 +1 0 0 0 -1
0 +1 0 0 0 -1
0 +1 0 0 0 -1
0 +1 0 0 0 -1
0 0 0 0 0 0
即在每一行都按照一维的方式来操作int sum=0,i,j;for(i=1;i<=n+1;i++)for(j=1;j<=n+1;j++)sum+=flag[i][j],real[i][j]=sum;
之后 real 数组里就存了最后的矩阵。输出即可。这个算法的复杂度是每次打标记O(n) ,总复杂度是O(mn+n^2)

【代碼】:[一維]

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
//#include<bits/stdc++.h>
using namespace std;typedef long long ll;
int a[1005][1005];
int x[1005][1005];
const int maxn=1e5+10;
void fun(int x1,int y1,int x2, int y2)
{for(int i=x1; i<=x2; i++){for(int j=y1; j<=y2; j++){a[i][j]++;}}
}
int main()
{int n,m;while(~scanf("%d%d",&n,&m)){int x1,y1,x2,y2;memset(a,0,sizeof(a));while(m--){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);for(int i=x1;i<=x2;i++){a[i][y1]++;a[i][y2+1]--;}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){x[i][j] = x[i][j-1] + a[i][j];printf("%d ",x[i][j]);}printf("\n");}}
}
/*
5 3
2 2 3 3
3 3 5 5
1 2 1 40 1 1 1 0
0 1 1 0 0
0 1 2 1 1
0 0 1 1 1
0 0 1 1 10 0 0 0 0         0 0 0 0 0        0 1 1 1 0
0 1 1 0 0         0 1 1 0 0        0 1 1 0 0
0 1 1 0 0    ->   0 1 2 1 1   ->   0 1 2 1 1
0 0 0 0 0         0 0 1 1 1        0 0 1 1 1
0 0 0 0 0         0 0 1 1 1        0 0 1 1 1*/
首先这题的主要思想很多大佬都讲了:就是差分,但是我的写法和他们的写法又不一样。本题数据范围为n<=1000,m<=1000。当n<=1000,m<=1000000甚至m<=10000000怎么办呢?这时不管是O(n)的修改,还是甚至是 O(log^2(n))O(log
2(n)) ,都是跑不过的。而我们有一个O(1)修改的做法:二维差分。设b[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1]。这样每次修改b[i][j]相当于对任意 i\le x,j \le yi≤x,j≤y 对a[x][y]做同样的修改然后每次修改就直接++b[x1][y1],--b[x2+1][y1],--b[x1][y2+1],++b[x2+1][y2+1]即可。也就是用 O(1)O(1) 的复杂度表示 O(n^2)O(n
2) 的覆盖(原话来自下面那篇题解“用O(1)复杂度来表示O(N)的覆盖”)最后再直接a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+b[i][j]还原出原序列即可。/* Author: CNYALI_LKLANG: C++PROG: 3397.cpp*/

[二維]

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
//#include<bits/stdc++.h>
using namespace std;typedef long long ll;
int a[1005][1005];
int x[1005][1005];
const int maxn=1e5+10;int main()
{int n,m;while(~scanf("%d%d",&n,&m)){int x1,y1,x2,y2;memset(a,0,sizeof(a));while(m--){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);a[x1][y1]++; //a[x2+1][y1]--;a[x1][y2+1]--; //a[x2+1][y2+1]++;}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1];printf("%d%c",a[i][j],j==n?'\n':' ');}}}
}


我们借助这个图片研究一下。假设在这个矩阵(二维数组)中,我们要求和的是上图中红色区域。现在我们已经预处理出了所有点的前缀和,现在给定两个点(x1,y1),(x2,y2),我们要求 以这两个点连线为对角线的一个子矩阵的数值之和。暴力做法直接挨个加这个我就不再多说了,反正早晚都得TLE,我们重点考虑用前缀和的快速做法。
首先我们可以把s[x2][y2]求出来,它代表整个大矩形的前缀和,然后我们分别减去它左边多出来的一块的前缀和和下边多出来一块的前缀和,这样就是最终答案了?
不是!这不是最终答案。可以发现,在我们剪掉这两个多出的区域时,下边的一小块被减了两次,但减两次显然是不合理的,我们应该加回来。。
所以对于一次的查询答案ans应该等于s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]。
这个二维前缀和也称差分序列。

转载于:https://www.cnblogs.com/Roni-i/p/9354177.html

洛谷 P3397 地毯 【二维差分标记】相关推荐

  1. 洛谷P3397 地毯

    洛谷P3397 地毯 二维差分 与一维差分类似 每次修改相当于只要修改4个地方就可以了 然后将差分数组来一次前缀和就能做好了 1 #include <cstdio> 2 #include ...

  2. 题161.洛谷P3131 前缀和与差分-Subsequences Summing to Sevens S

    文章目录 题161.洛谷P3131 前缀和与差分-Subsequences Summing to Sevens S 一.题目 二.题解 题161.洛谷P3131 前缀和与差分-Subsequences ...

  3. HDU - 6514 Monitor(二维差分)

    题目链接:点击查看 题目大意:给出一个n*m的矩阵,开始全部初始化为0,然后给出一系列的小矩阵的范围,小矩阵中的格子全部变为1,最后再给出一些查询,查询矩阵范围内是否所有的格子都是1,是的话输出yes ...

  4. 一维前缀和,二维前缀和,一维差分,二维差分(翻译)

    练习一道题目 输入一个长度为n的整数序列. 接下来再输入m个询问,每个询问输入一对l, r. 对于每个询问,输出原序列中从第l个数到第r个数的和. 输入格式 第一行包含两个整数n和m. 第二行包含n个 ...

  5. 2020ICPC·小米 网络选拔赛第一场(Matrix Subtraction (二维差分))

    题目传送门 Matrix Subtraction 题目大意 给你一个 n × m n×m n×m的矩阵,每次可从矩阵中选择一个大小为 a × b a×b a×b的矩阵,使得该子矩阵的值全部减一 求最后 ...

  6. 激光导弹Gundam Unicorn(二维前缀和and二维差分)

    激光炸弹和Gundam Unicorn是二维前缀和和二位差分的综合应用. 首先是一二维差分,前缀和的模板前缀和与差分 图文并茂 超级详细整理(全网最通俗易懂)_林深不见鹿 的博客-CSDN博客_前缀和 ...

  7. 差分——(2)二维差分

    前面部分我们介绍了一维差分,https://blog.csdn.net/justidle/article/details/103761632.下面我们扩展一下,来介绍二维差分. 什么是二维差分 我们有 ...

  8. [选拔赛2 NOIP2018雅礼集训 Day3 u,v,w]玩个三角形(二维差分),玩个球(状压DP+map),玩个树(树上DP)

    文章目录 T1:玩个三角形 title solution code T2:玩个球 title solution code T3:玩个树 title solution code T1:玩个三角形 tit ...

  9. 【牛客 - 331B】炫酷五子棋(STLset 或Hash,tricks,二维map标记)

    题干: 五子棋是一个简单的双人游戏. 小希最近在思索一种更好玩的五子棋.她希望胜利不再是谁先五子连珠谁赢,而变成谁落子后,该子与之前的子五子连珠的次数更多才能胜利. 但是如果是在普通的棋盘上,这个游戏 ...

  10. LeetCode 2132. 用邮票贴满网格图(DP/二维差分)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个 m x n 的二进制矩阵 grid ,每个格子要么为 0 (空)要么为 1 (被占据). 给你邮票的尺寸为 stampHeight x stam ...

最新文章

  1. Linux系统备份策略探讨
  2. 关于线程池你不得不知道的一些设置
  3. JAVA RPC:从上手到爱不释手
  4. Sublime Text 快捷键
  5. 从头搭建 IntelliJ IDEA 环境,从放弃到爱不释手!
  6. 笔记-计算机网络基础-5G
  7. MyBatis学习总结(16)——Mybatis使用的几个建议
  8. py-faster-rcnn代码roidb.py的解读
  9. 深入进货单-价格跟踪----宇然电脑公司管理软件
  10. 软件本地化 pdf_软件本地化与标准翻译
  11. JavaScript中的基本表单验证
  12. maven常见问题问答 收藏
  13. 开源的 DNS 转发软件 Dnsmasq 被曝7个漏洞,可劫持数百万台设备
  14. VMware Workstation pro无法在Windows上运行的解决方法
  15. jsp1201高校实习实训系统
  16. 趋高机器视觉之机械手臂的应用
  17. 二工大计算机专业,两电一邮与哈工大:计算机专业哪所实力最强?看完就知道...
  18. windows 20003 扩展安装后不成功的原因
  19. 双光耦开关电源电路图_光耦开关电源电路图大全(光电耦合器/可控精密稳压源)...
  20. Java 简易五子棋游戏的编写

热门文章

  1. VLC框架总结(二)VLC源码及各modules功能介绍
  2. android 白平衡,保存Android相机焦点和白平衡状态
  3. php 修改文件的权限_php修改文件权限
  4. iphone投屏ipad_幕享免费无线投屏:你朝思暮想的屏幕互联方式
  5. 目标检测的数据增强 -- 代码实现
  6. python整型为空的情况_深度剖析凭什么python中整型不会溢出
  7. kvm虚拟机_关于虚拟机管理KVM,基本操作都在这里,懒人必备,拿去收藏
  8. 逆向 Mac 应用 Bartender
  9. 汤立波:车联网最新发展动态
  10. 【ROR】基础0-在vagrant中配置ror环境